mirror of
https://gitee.com/openharmony/ability_idl_tool
synced 2024-11-27 01:20:37 +00:00
工具合一hdi codegen部分上库
Signed-off-by: millerluo <luoxueting2@huawei.com> Change-Id: I294d55182142f967bcd25f0d1327558f50e18e62
This commit is contained in:
parent
c80c144c9a
commit
0c8d118a3b
@ -35,9 +35,12 @@ OpenHarmony IDL接口描述语言主要用于:
|
||||
```
|
||||
foundation/ability/idl_tool
|
||||
├── ast # idl语法解析定义代码
|
||||
├── codegen # 跨进程通信模板生成模块代码
|
||||
├── codegen # 模板生成模块代码
|
||||
├── hash # hash生成模块代码
|
||||
├── lexer # 词法解析模块代码
|
||||
├── metadata # matedata自定义数据解析模块代码
|
||||
├── parser # idl解析模块代码
|
||||
├── parser # 语法解析模块代码
|
||||
├── preprocessor # 预处理模块代码
|
||||
├── test # 测试目录
|
||||
└── util # 公共方法代码
|
||||
```
|
||||
|
850
idl_tool_2/codegen/HDI/c/c_client_proxy_code_emitter.cpp
Normal file
850
idl_tool_2/codegen/HDI/c/c_client_proxy_code_emitter.cpp
Normal file
@ -0,0 +1,850 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "c_client_proxy_code_emitter.h"
|
||||
#include "util/file.h"
|
||||
#include "util/logger.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
bool CClientProxyCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
|
||||
{
|
||||
if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
|
||||
directory_ = GetFileParentPath(targetDirectory);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!File::CreateParentDir(directory_)) {
|
||||
Logger::E("CClientProxyCodeEmitter", "Create '%s' failed!", directory_.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitCode()
|
||||
{
|
||||
switch (mode_) {
|
||||
case GenMode::PASSTHROUGH: {
|
||||
if (!interface_->IsSerializable()) {
|
||||
EmitPassthroughProxySourceFile();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GenMode::IPC:
|
||||
case GenMode::KERNEL: {
|
||||
EmitProxySourceFile();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitPassthroughProxySourceFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.c", directory_.c_str(), FileName(proxyName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitPassthroughProxyInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitLogTagMacro(sb, FileName(proxyName_));
|
||||
sb.Append("\n");
|
||||
EmitProxyGetMethodImpl(sb);
|
||||
sb.Append("\n");
|
||||
EmitPassthroughGetInstanceMethod(sb);
|
||||
sb.Append("\n");
|
||||
EmitProxyReleaseMethodImpl(sb);
|
||||
sb.Append("\n");
|
||||
EmitPassthroughReleaseInstanceMethod(sb);
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitPassthroughProxyInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitPassthroughGetInstanceMethod(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("struct %s *%sGetInstance(const char *serviceName, bool isStub)\n",
|
||||
interfaceName_.c_str(), interfaceName_.c_str());
|
||||
sb.Append("{\n");
|
||||
EmitProxyLoadOrUnLoadHdiImpl("serviceName", true, sb, TAB);
|
||||
sb.Append(TAB).Append("return NULL;\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitPassthroughReleaseInstanceMethod(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("void %sReleaseInstance(const char *serviceName, struct %s *instance, bool isStub)\n",
|
||||
interfaceName_.c_str(), interfaceName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("if (instance == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
EmitProxyLoadOrUnLoadHdiImpl("serviceName", false, sb, TAB);
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxySourceFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.c", directory_.c_str(), FileName(proxyName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitProxyInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitLogTagMacro(sb, FileName(proxyName_));
|
||||
sb.Append("\n");
|
||||
EmitProxyDefinition(sb);
|
||||
sb.Append("\n");
|
||||
EmitUtilMethods(sb, true);
|
||||
sb.Append("\n");
|
||||
EmitUtilMethods(sb, false);
|
||||
sb.Append("\n");
|
||||
if (mode_ != GenMode::KERNEL) {
|
||||
EmitProxyCallMethodImpl(sb);
|
||||
} else {
|
||||
EmitProxyKernelCallMethodImpl(sb);
|
||||
}
|
||||
sb.Append("\n");
|
||||
EmitProxyMethodImpls(sb);
|
||||
sb.Append("\n");
|
||||
EmitProxyConstruction(sb);
|
||||
sb.Append("\n");
|
||||
EmitProxyExternalMethodImpl(sb);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
|
||||
headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
|
||||
GetHeaderOtherLibInclusions(headerFiles);
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
|
||||
{
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_sbuf");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "osal_mem");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
|
||||
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_io_service_if");
|
||||
} else {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "servmgr_hdi");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_dlist");
|
||||
if (!interface_->IsSerializable()) {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "stub_collector");
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
|
||||
AutoPtr<ASTType> paramType = param->GetType();
|
||||
if ((param->GetAttribute() == ASTParamAttr::PARAM_IN) &&
|
||||
(paramType->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "stub_collector");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyDefinition(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("struct %sProxy {\n", baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("struct %s impl;\n", interfaceName_.c_str());
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
sb.Append(TAB).Append("struct HdfIoService *serv;\n");
|
||||
} else {
|
||||
sb.Append(TAB).Append("struct HdfRemoteService *remote;\n");
|
||||
}
|
||||
|
||||
sb.Append("};\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyCallMethodImpl(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("static int32_t %sProxyCall(struct %s *self, int32_t id, struct HdfSBuf *data,\n",
|
||||
baseName_.c_str(), interfaceName_.c_str());
|
||||
sb.Append(TAB).Append("struct HdfSBuf *reply, bool isOneWay)\n");
|
||||
sb.Append("{\n");
|
||||
|
||||
std::string remoteName = "remote";
|
||||
sb.Append(TAB).AppendFormat("struct HdfRemoteService *%s = self->AsObject(self);\n", remoteName.c_str());
|
||||
sb.Append(TAB).AppendFormat("if (%s == NULL ||\n", remoteName.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("%s->dispatcher == NULL ||\n", remoteName.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("%s->dispatcher->Dispatch == NULL ||\n", remoteName.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("%s->dispatcher->DispatchAsync == NULL) {\n", remoteName.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: Invalid HdfRemoteService obj\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
|
||||
sb.Append(TAB).AppendFormat("if (isOneWay) {\n");
|
||||
sb.Append(TAB).Append(TAB).AppendFormat(
|
||||
"return %s->dispatcher->DispatchAsync(%s, id, data, reply);\n", remoteName.c_str(), remoteName.c_str());
|
||||
sb.Append(TAB).AppendFormat("} else {\n");
|
||||
sb.Append(TAB).Append(TAB).AppendFormat(
|
||||
"return %s->dispatcher->Dispatch(%s, id, data, reply);\n", remoteName.c_str(), remoteName.c_str());
|
||||
sb.Append(TAB).AppendFormat("}\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyKernelCallMethodImpl(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("static int32_t %sProxyCall(struct %s *self, int32_t id, struct HdfSBuf *data,\n",
|
||||
baseName_.c_str(), interfaceName_.c_str());
|
||||
sb.Append(TAB).Append("struct HdfSBuf *reply)\n");
|
||||
sb.Append("{\n");
|
||||
|
||||
std::string remoteName = "serv";
|
||||
sb.Append(TAB).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(self, struct %sProxy, impl);\n",
|
||||
baseName_.c_str(), baseName_.c_str(), remoteName.c_str());
|
||||
sb.Append(TAB).AppendFormat("struct HdfIoService *%s = proxy->%s;\n", remoteName.c_str(), remoteName.c_str());
|
||||
|
||||
sb.Append(TAB).AppendFormat("if (%s == NULL ||\n", remoteName.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("%s->dispatcher == NULL ||\n", remoteName.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("%s->dispatcher->Dispatch == NULL) {\n", remoteName.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: Invalid HdfRemoteService obj\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
|
||||
sb.Append(TAB).AppendFormat("return %s->dispatcher->Dispatch(", remoteName.c_str());
|
||||
sb.AppendFormat("(struct HdfObject *)&(%s->object), id, data, reply);\n", remoteName.c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyMethodImpls(StringBuilder &sb)
|
||||
{
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
EmitProxyMethodImpl(method, sb);
|
||||
sb.Append("\n");
|
||||
}
|
||||
|
||||
EmitProxyMethodImpl(interface_->GetVersionMethod(), sb);
|
||||
|
||||
if (mode_ != GenMode::KERNEL) {
|
||||
sb.Append("\n");
|
||||
EmitProxyAsObjectMethodImpl(sb);
|
||||
}
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyMethodImpl(const AutoPtr<ASTMethod> &method, StringBuilder &sb)
|
||||
{
|
||||
if (method->GetParameterNumber() == 0) {
|
||||
sb.AppendFormat("static int32_t %sProxy%s(struct %s *self)\n", baseName_.c_str(), method->GetName().c_str(),
|
||||
interfaceName_.c_str());
|
||||
} else {
|
||||
StringBuilder paramStr;
|
||||
paramStr.AppendFormat("static int32_t %sProxy%s(", baseName_.c_str(), method->GetName().c_str());
|
||||
paramStr.AppendFormat("struct %s *self, ", interfaceName_.c_str());
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
EmitInterfaceMethodParameter(param, paramStr, "");
|
||||
if (i + 1 < method->GetParameterNumber()) {
|
||||
paramStr.Append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
paramStr.Append(")");
|
||||
sb.Append(SpecificationParam(paramStr, TAB));
|
||||
sb.Append("\n");
|
||||
}
|
||||
EmitProxyMethodBody(method, sb, "");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyMethodBody(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("int32_t %s = HDF_FAILURE;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
|
||||
// Local variable definitions must precede all execution statements.
|
||||
EmitMethodNeedLoopVar(method, true, false, sb, prefix + TAB);
|
||||
sb.Append("\n");
|
||||
EmitCreateBuf(HdiTypeEmitter::dataParcelName_, HdiTypeEmitter::replyParcelName_, sb, prefix + TAB);
|
||||
sb.Append("\n");
|
||||
EmitCheckThisPointer(sb, prefix + TAB);
|
||||
|
||||
if (mode_ != GenMode::KERNEL) {
|
||||
sb.Append("\n");
|
||||
EmitWriteInterfaceToken(HdiTypeEmitter::dataParcelName_, sb, prefix + TAB);
|
||||
}
|
||||
|
||||
sb.Append("\n");
|
||||
EmitWriteFlagOfNeedSetMem(method, HdiTypeEmitter::dataParcelName_, sb, prefix + TAB);
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
|
||||
if (param->GetAttribute() == ASTParamAttr::PARAM_IN) {
|
||||
typeEmitter->EmitCWriteVar(TypeMode::PARAM_IN, param->GetName(), finishedLabel_, sb, prefix + TAB);
|
||||
sb.Append("\n");
|
||||
} else {
|
||||
typeEmitter->EmitCProxyWriteOutVar(param->GetName(), finishedLabel_, sb, prefix + TAB);
|
||||
}
|
||||
}
|
||||
|
||||
EmitStubCallMethod(method, sb, prefix + TAB);
|
||||
sb.Append("\n");
|
||||
|
||||
if (!method->IsOneWay()) {
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
if (param->GetAttribute() == ASTParamAttr::PARAM_OUT) {
|
||||
EmitReadProxyMethodParameter(param, finishedLabel_, sb, prefix + TAB);
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sb.Append(prefix).AppendFormat("%s:\n", finishedLabel_);
|
||||
EmitReleaseBuf(HdiTypeEmitter::dataParcelName_, HdiTypeEmitter::replyParcelName_, sb, prefix + TAB);
|
||||
|
||||
sb.Append(prefix + TAB).AppendFormat("return %s;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitCreateBuf(const std::string &dataBufName,
|
||||
const std::string &replyBufName, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
sb.Append(prefix).AppendFormat("struct HdfSBuf *%s = HdfSbufObtainDefaultSize();\n", dataBufName.c_str());
|
||||
sb.Append(prefix).AppendFormat("struct HdfSBuf *%s = HdfSbufObtainDefaultSize();\n", replyBufName.c_str());
|
||||
} else {
|
||||
sb.Append(prefix).AppendFormat("struct HdfSBuf *%s = HdfSbufTypedObtain(SBUF_IPC);\n", dataBufName.c_str());
|
||||
sb.Append(prefix).AppendFormat("struct HdfSBuf *%s = HdfSbufTypedObtain(SBUF_IPC);\n", replyBufName.c_str());
|
||||
}
|
||||
|
||||
sb.Append("\n");
|
||||
sb.Append(prefix).AppendFormat("if (%s == NULL || %s == NULL) {\n", dataBufName.c_str(), replyBufName.c_str());
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: HdfSubf malloc failed!\", __func__);\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", finishedLabel_);
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitCheckThisPointer(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).Append("if (self == NULL) {\n");
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid interface object\", __func__);\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_OBJECT;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", finishedLabel_);
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitWriteInterfaceToken(
|
||||
const std::string &dataBufName, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"if (!HdfRemoteServiceWriteInterfaceToken(self->AsObject(self), %s)) {\n", dataBufName.c_str());
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: write interface token failed!\", __func__);\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", finishedLabel_);
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitWriteFlagOfNeedSetMem(const AutoPtr<ASTMethod> &method,
|
||||
const std::string &dataBufName, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
if (NeedFlag(method)) {
|
||||
sb.Append(prefix).AppendFormat("if (!HdfSbufWriteUint8(%s, 1)) {\n", dataBufName.c_str());
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: write flag of memory setting failed!\", __func__);\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", finishedLabel_);
|
||||
sb.Append(prefix).Append("}\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitReleaseBuf(const std::string &dataBufName,
|
||||
const std::string &replyBufName, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("if (%s != NULL) {\n", dataBufName.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("HdfSbufRecycle(%s);\n", dataBufName.c_str());
|
||||
sb.Append(prefix).Append("}\n");
|
||||
sb.Append(prefix).AppendFormat("if (%s != NULL) {\n", replyBufName.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("HdfSbufRecycle(%s);\n", replyBufName.c_str());
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitReadProxyMethodParameter(const AutoPtr<ASTParameter> ¶m,
|
||||
const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
AutoPtr<ASTType> type = param->GetType();
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
|
||||
std::string name = param->GetName();
|
||||
if (type->GetTypeKind() == TypeKind::TYPE_STRING) {
|
||||
std::string cloneName = StringHelper::Format("%sCopy", name.c_str());
|
||||
typeEmitter->EmitCProxyReadVar(cloneName, false, gotoLabel, sb, prefix);
|
||||
sb.Append(prefix).AppendFormat("if (strcpy_s(%s, %sLen, %s) != EOK) {\n", name.c_str(),
|
||||
name.c_str(), cloneName.c_str());
|
||||
sb.Append(prefix + TAB)
|
||||
.AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", name.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
|
||||
sb.Append(prefix).Append("}\n");
|
||||
} else if (type->GetTypeKind() == TypeKind::TYPE_UNION) {
|
||||
std::string cpName = StringHelper::Format("%sCp", name.c_str());
|
||||
typeEmitter->EmitCProxyReadVar(cpName, false, gotoLabel, sb, prefix);
|
||||
sb.Append(prefix).AppendFormat("if (memcpy_s(%s, sizeof(%s), %s, sizeof(%s)) != EOK) {\n",
|
||||
name.c_str(), typeEmitter->EmitCType().c_str(), cpName.c_str(), typeEmitter->EmitCType().c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to memcpy %s\", __func__);\n",
|
||||
name.c_str());
|
||||
sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
} else {
|
||||
typeEmitter->EmitCProxyReadVar(name, false, gotoLabel, sb, prefix);
|
||||
}
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitStubCallMethod(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
if (mode_ != GenMode::KERNEL) {
|
||||
sb.Append(prefix).AppendFormat("%s = %sCall(self, %s, %s, %s, %s);\n", HdiTypeEmitter::errorCodeName_.c_str(),
|
||||
proxyName_.c_str(), EmitMethodCmdID(method).c_str(), HdiTypeEmitter::dataParcelName_.c_str(),
|
||||
HdiTypeEmitter::replyParcelName_.c_str(),
|
||||
method->IsOneWay() ? "true" : "false");
|
||||
} else {
|
||||
sb.Append(prefix).AppendFormat("%s = %sCall(self, %s, %s, %s);\n", HdiTypeEmitter::errorCodeName_.c_str(),
|
||||
proxyName_.c_str(), EmitMethodCmdID(method).c_str(), HdiTypeEmitter::dataParcelName_.c_str(),
|
||||
HdiTypeEmitter::replyParcelName_.c_str());
|
||||
}
|
||||
sb.Append(prefix).AppendFormat("if (%s != HDF_SUCCESS) {\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat(
|
||||
"HDF_LOGE(\"%%{public}s: call failed! error code is %%{public}d\", __func__, %s);\n",
|
||||
HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", finishedLabel_);
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyAsObjectMethodImpl(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("static struct HdfRemoteService *%sProxyAsObject(struct %s *self)\n", baseName_.c_str(),
|
||||
interfaceName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("if (self == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return NULL;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
sb.Append(TAB).AppendFormat(
|
||||
"struct %sProxy *proxy = CONTAINER_OF(self, struct %sProxy, impl);\n", baseName_.c_str(), baseName_.c_str());
|
||||
sb.Append(TAB).Append("return proxy->remote;\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyConstruction(StringBuilder &sb) const
|
||||
{
|
||||
std::string objName = "impl";
|
||||
sb.AppendFormat(
|
||||
"static void %sProxyConstruct(struct %s *%s)\n", baseName_.c_str(), interfaceName_.c_str(), objName.c_str());
|
||||
sb.Append("{\n");
|
||||
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
sb.Append(TAB).AppendFormat("%s->%s = %sProxy%s;\n", objName.c_str(), method->GetName().c_str(),
|
||||
baseName_.c_str(), method->GetName().c_str());
|
||||
}
|
||||
|
||||
AutoPtr<ASTMethod> getVerMethod = interface_->GetVersionMethod();
|
||||
sb.Append(TAB).AppendFormat("%s->%s = %sProxy%s;\n", objName.c_str(), getVerMethod->GetName().c_str(),
|
||||
baseName_.c_str(), getVerMethod->GetName().c_str());
|
||||
|
||||
if (mode_ != GenMode::KERNEL) {
|
||||
sb.Append(TAB).AppendFormat("%s->AsObject = %sProxyAsObject;\n", objName.c_str(), baseName_.c_str());
|
||||
}
|
||||
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyExternalMethodImpl(StringBuilder &sb)
|
||||
{
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
EmitKernelProxyExternalMethodImpl(sb);
|
||||
} else if (interface_->IsSerializable()) {
|
||||
EmitSerialProxyExternalMethodImpl(sb);
|
||||
} else {
|
||||
EmitProxyExternalMethod(sb);
|
||||
}
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitKernelProxyExternalMethodImpl(StringBuilder &sb)
|
||||
{
|
||||
std::string remoteName = "serv";
|
||||
|
||||
EmitKernelProxyGetMethodImpl(sb);
|
||||
sb.Append("\n");
|
||||
EmitKernelProxyGetInstanceMethodImpl(remoteName, sb);
|
||||
sb.Append("\n");
|
||||
EmitKernelProxyReleaseMethodImpl(remoteName, "HdfIoServiceRecycle", sb);
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitKernelProxyGetMethodImpl(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("struct %s *%sGet()\n", interfaceName_.c_str(), interfaceName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).AppendFormat("return %sGetInstance(\"%s\");\n", interfaceName_.c_str(),
|
||||
FileName(implName_).c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitKernelProxyGetInstanceMethodImpl(const std::string &remoteName,
|
||||
StringBuilder &sb) const
|
||||
{
|
||||
std::string objName = "client";
|
||||
std::string serMajorName = "serMajorVer";
|
||||
std::string serMinorName = "serMinorVer";
|
||||
std::string serviceName = "serviceName";
|
||||
|
||||
sb.AppendFormat("struct %s *%sGetInstance(const char* %s)\n", interfaceName_.c_str(), interfaceName_.c_str(),
|
||||
serviceName.c_str());
|
||||
sb.Append("{\n");
|
||||
EmitProxyGetRemoteService(remoteName, serviceName, sb, TAB);
|
||||
sb.Append("\n");
|
||||
EmitProxyCreateProxyObject(objName, remoteName, "HdfIoServiceRecycle", sb, TAB);
|
||||
sb.Append("\n");
|
||||
EmitProxyCheckVersion(objName, serMajorName, serMinorName, sb, TAB);
|
||||
sb.Append("\n");
|
||||
sb.Append(TAB).AppendFormat("return %s;\n", objName.c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitKernelProxyReleaseMethodImpl(
|
||||
const std::string &remoteName, const std::string &recycleFuncName, StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("void %sRelease(struct %s *instance)\n", interfaceName_.c_str(), interfaceName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("if (instance == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
sb.Append(TAB).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(instance, struct %sProxy, impl);\n",
|
||||
baseName_.c_str(), baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("%s(proxy->%s);\n", recycleFuncName.c_str(), remoteName.c_str());
|
||||
sb.Append(TAB).Append("OsalMemFree(proxy);\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitSerialProxyExternalMethodImpl(StringBuilder &sb)
|
||||
{
|
||||
std::string serMajorName = "serMajorVer";
|
||||
std::string serMinorName = "serMinorVer";
|
||||
std::string remoteName = "remote";
|
||||
|
||||
EmitIfaceProxyGetMethodImpl(serMajorName, serMinorName, remoteName, sb);
|
||||
sb.Append("\n");
|
||||
|
||||
if (interface_->IsCallback()) {
|
||||
EmitCbProxyReleaseMethodImpl(remoteName, "HdfRemoteServiceRecycle", sb);
|
||||
} else {
|
||||
EmitIfaceProxyReleaseMethodImpl(remoteName, "HdfRemoteServiceRecycle", sb);
|
||||
}
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitIfaceProxyGetMethodImpl(const std::string &serMajorName,
|
||||
const std::string &serMinorName, const std::string &remoteName, StringBuilder &sb)
|
||||
{
|
||||
std::string objName = "client";
|
||||
sb.AppendFormat("struct %s *%sGet(struct HdfRemoteService *%s)\n", interfaceName_.c_str(), interfaceName_.c_str(),
|
||||
remoteName.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", remoteName.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("HDF_LOGE(\"%%{public}s: remote is null\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return NULL;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
EmitProxySetInterfaceDesc(remoteName, "HdfRemoteServiceRecycle", sb, TAB);
|
||||
sb.Append("\n");
|
||||
EmitProxyCreateProxyObject(objName, remoteName, "HdfRemoteServiceRecycle", sb, TAB);
|
||||
sb.Append("\n");
|
||||
EmitProxyCheckVersion(objName, serMajorName, serMinorName, sb, TAB);
|
||||
sb.Append("\n");
|
||||
sb.Append(TAB).AppendFormat("return %s;\n", objName.c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitIfaceProxyReleaseMethodImpl(
|
||||
const std::string &remoteName, const std::string &recycleFuncName, StringBuilder &sb) const
|
||||
{
|
||||
std::string implReleaseMethodName = StringHelper::Format("%sImplRelease", interfaceName_.c_str());
|
||||
sb.AppendFormat("void %s(struct %s *instance) __attribute__((weak));\n", implReleaseMethodName.c_str(),
|
||||
interfaceName_.c_str());
|
||||
sb.AppendFormat("void %sRelease(struct %s *instance, bool isStub)\n", interfaceName_.c_str(),
|
||||
interfaceName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("if (instance == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
|
||||
sb.Append(TAB).Append("if (isStub) {\n");
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("if (%s != NULL) {\n", implReleaseMethodName.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append(TAB).AppendFormat("%s(instance);\n", implReleaseMethodName.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("}\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
|
||||
sb.Append(TAB).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(instance, struct %sProxy, impl);\n",
|
||||
baseName_.c_str(), baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("%s(proxy->%s);\n", recycleFuncName.c_str(), remoteName.c_str());
|
||||
sb.Append(TAB).Append("OsalMemFree(proxy);\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitCbProxyReleaseMethodImpl(const std::string &remoteName,
|
||||
const std::string &recycleFuncName, StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("void %sRelease(struct %s *instance)\n", interfaceName_.c_str(), interfaceName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("if (instance == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
sb.Append(TAB).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(instance, struct %sProxy, impl);\n",
|
||||
baseName_.c_str(), baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("%s(proxy->%s);\n", recycleFuncName.c_str(), remoteName.c_str());
|
||||
sb.Append(TAB).Append("OsalMemFree(proxy);\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyExternalMethod(StringBuilder &sb)
|
||||
{
|
||||
std::string remoteName = "remote";
|
||||
std::string serviceName = "serviceName";
|
||||
|
||||
EmitProxyGetMethodImpl(sb);
|
||||
sb.Append("\n");
|
||||
EmitProxyGetInstanceMethodImpl(remoteName, serviceName, sb);
|
||||
sb.Append("\n");
|
||||
EmitProxyReleaseMethodImpl(sb);
|
||||
sb.Append("\n");
|
||||
EmitProxyReleaseInstanceMethodImpl(serviceName, remoteName, "HdfRemoteServiceRecycle", sb);
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyGetMethodImpl(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("struct %s *%sGet(bool isStub)\n", interfaceName_.c_str(), interfaceName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).AppendFormat("return %sGetInstance(\"%s\", isStub);\n", interfaceName_.c_str(),
|
||||
FileName(implName_).c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyGetInstanceMethodImpl(const std::string &remoteName,
|
||||
const std::string &serviceName, StringBuilder &sb) const
|
||||
{
|
||||
std::string objName = "client";
|
||||
std::string serMajorName = "serMajorVer";
|
||||
std::string serMinorName = "serMinorVer";
|
||||
|
||||
sb.AppendFormat("struct %s *%sGetInstance(const char *%s, bool isStub)\n", interfaceName_.c_str(),
|
||||
interfaceName_.c_str(), serviceName.c_str());
|
||||
sb.Append("{\n");
|
||||
EmitProxyLoadOrUnLoadHdiImpl(serviceName, true, sb, TAB);
|
||||
sb.Append("\n");
|
||||
EmitProxyGetRemoteService(remoteName, serviceName, sb, TAB);
|
||||
sb.Append("\n");
|
||||
EmitProxySetInterfaceDesc(remoteName, "HdfRemoteServiceRecycle", sb, TAB);
|
||||
sb.Append("\n");
|
||||
EmitProxyCreateProxyObject(objName, remoteName, "HdfRemoteServiceRecycle", sb, TAB);
|
||||
sb.Append("\n");
|
||||
EmitProxyCheckVersion(objName, serMajorName, serMinorName, sb, TAB);
|
||||
sb.Append("\n");
|
||||
sb.Append(TAB).AppendFormat("return %s;\n", objName.c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyGetRemoteService(const std::string &remoteName,
|
||||
const std::string &serviceName, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
if (mode_ != GenMode::KERNEL) {
|
||||
sb.Append(prefix).Append("struct HDIServiceManager *serviceMgr = HDIServiceManagerGet();\n");
|
||||
sb.Append(prefix).Append("if (serviceMgr == NULL) {\n");
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: HDIServiceManager not found!\", __func__);\n");
|
||||
sb.Append(prefix + TAB).Append("return NULL;\n");
|
||||
sb.Append(prefix).Append("}\n\n");
|
||||
sb.Append(prefix).AppendFormat("struct HdfRemoteService *%s = ", remoteName.c_str());
|
||||
sb.AppendFormat("serviceMgr->GetService(serviceMgr, %s);\n", serviceName.c_str());
|
||||
sb.Append(prefix).Append("HDIServiceManagerRelease(serviceMgr);\n");
|
||||
sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", remoteName.c_str());
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to get remote!\", __func__);\n");
|
||||
sb.Append(prefix + TAB).Append("return NULL;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
} else {
|
||||
sb.Append(prefix).AppendFormat("struct HdfIoService *%s = ", remoteName.c_str());
|
||||
sb.AppendFormat("HdfIoServiceBind(%s);\n", serviceName.c_str());
|
||||
sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", remoteName.c_str());
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to get io service!\", __func__);\n");
|
||||
sb.Append(prefix + TAB).Append("return NULL;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxySetInterfaceDesc(const std::string &remoteName,
|
||||
const std::string &recycleFuncName, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("if (!HdfRemoteServiceSetInterfaceDesc(%s, %s)) {\n", remoteName.c_str(),
|
||||
EmitDescMacroName().c_str());
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: set interface token failed!\", __func__);\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("%s(%s);\n", recycleFuncName.c_str(), remoteName.c_str());
|
||||
sb.Append(prefix + TAB).Append("return NULL;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyCreateProxyObject(const std::string &clientObjName,
|
||||
const std::string &remoteName, const std::string &recycleFuncName, StringBuilder &sb,
|
||||
const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("struct %sProxy *proxy = (struct %sProxy *)OsalMemCalloc(sizeof(struct %sProxy));\n",
|
||||
baseName_.c_str(), baseName_.c_str(), baseName_.c_str());
|
||||
sb.Append(prefix).Append("if (proxy == NULL) {\n");
|
||||
sb.Append(prefix + TAB)
|
||||
.AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s proxy failed!\", __func__);\n", interfaceName_.c_str());
|
||||
if (!interface_->IsSerializable()) {
|
||||
sb.Append(prefix + TAB).AppendFormat("%s(%s);\n", recycleFuncName.c_str(), remoteName.c_str());
|
||||
}
|
||||
sb.Append(prefix + TAB).Append("return NULL;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
sb.Append("\n");
|
||||
sb.Append(prefix).AppendFormat("proxy->%s = %s;\n", remoteName.c_str(), remoteName.c_str());
|
||||
sb.Append(prefix).AppendFormat("%sProxyConstruct(&proxy->impl);\n", baseName_.c_str());
|
||||
sb.Append(prefix).AppendFormat("struct %s *%s = &proxy->impl;\n", interfaceName_.c_str(), clientObjName.c_str());
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyCheckVersion(const std::string &clientObjName, const std::string &serMajorName,
|
||||
const std::string &serMinorName, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("uint32_t %s = 0;\n", serMajorName.c_str());
|
||||
sb.Append(prefix).AppendFormat("uint32_t %s = 0;\n", serMinorName.c_str());
|
||||
sb.Append(prefix).AppendFormat("int32_t %s = %s->GetVersion(%s, &%s, &%s);\n",
|
||||
HdiTypeEmitter::errorCodeName_.c_str(), clientObjName.c_str(), clientObjName.c_str(), serMajorName.c_str(),
|
||||
serMinorName.c_str());
|
||||
sb.Append(prefix).AppendFormat("if (%s != HDF_SUCCESS) {\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: get version failed!\", __func__);\n");
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
sb.Append(prefix + TAB).AppendFormat("%sRelease(%s);\n", interfaceName_.c_str(), clientObjName.c_str());
|
||||
} else if (interface_->IsCallback()) {
|
||||
sb.Append(prefix + TAB).AppendFormat("%sRelease(%s);\n", interfaceName_.c_str(), clientObjName.c_str());
|
||||
} else {
|
||||
sb.Append(prefix + TAB).AppendFormat("%sRelease(false, %s);\n", interfaceName_.c_str(), clientObjName.c_str());
|
||||
}
|
||||
|
||||
sb.Append(prefix + TAB).Append("return NULL;\n");
|
||||
sb.Append(prefix).Append("}\n\n");
|
||||
sb.Append(prefix).AppendFormat("if (%s != %s) {\n", serMajorName.c_str(), majorVerName_.c_str());
|
||||
sb.Append(prefix + 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 + TAB + TAB).AppendFormat("%s, %s, %s, %s);\n", serMajorName.c_str(), serMinorName.c_str(),
|
||||
majorVerName_.c_str(), minorVerName_.c_str());
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
sb.Append(prefix + TAB).AppendFormat("%sRelease(%s);\n", interfaceName_.c_str(), clientObjName.c_str());
|
||||
} else if (interface_->IsCallback()) {
|
||||
sb.Append(prefix + TAB).AppendFormat("%sRelease(%s);\n", interfaceName_.c_str(), clientObjName.c_str());
|
||||
} else {
|
||||
sb.Append(prefix + TAB).AppendFormat("%sRelease(false, %s);\n", interfaceName_.c_str(), clientObjName.c_str());
|
||||
}
|
||||
sb.Append(prefix + TAB).Append("return NULL;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyReleaseMethodImpl(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat(
|
||||
"void %sRelease(struct %s *instance, bool isStub)\n", interfaceName_.c_str(), interfaceName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).AppendFormat(
|
||||
"%sReleaseInstance(\"%s\", instance, isStub);\n", interfaceName_.c_str(), FileName(implName_).c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyReleaseInstanceMethodImpl(const std::string &serviceName,
|
||||
const std::string &remoteName, const std::string &recycleFuncName, StringBuilder &sb)
|
||||
{
|
||||
sb.AppendFormat("void %sReleaseInstance(const char *%s, struct %s *instance, bool isStub)\n",
|
||||
interfaceName_.c_str(), serviceName.c_str(), interfaceName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("if (instance == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
EmitProxyLoadOrUnLoadHdiImpl(serviceName, false, sb, TAB);
|
||||
sb.Append("\n");
|
||||
sb.Append(TAB).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(instance, struct %sProxy, impl);\n",
|
||||
baseName_.c_str(), baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("%s(proxy->%s);\n", recycleFuncName.c_str(), remoteName.c_str());
|
||||
sb.Append(TAB).Append("OsalMemFree(proxy);\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitProxyLoadOrUnLoadHdiImpl(const std::string &serviceName, bool isLoad,
|
||||
StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
std::string instName = "instName";
|
||||
sb.Append(prefix).Append("if (isStub) {\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("const char *%s = %s;\n", instName.c_str(), serviceName.c_str());
|
||||
sb.Append(prefix + TAB)
|
||||
.AppendFormat("if (strcmp(%s, \"%s\") == 0) {\n", instName.c_str(), FileName(implName_).c_str());
|
||||
sb.Append(prefix + TAB + TAB).AppendFormat("%s = \"service\";\n", instName.c_str());
|
||||
sb.Append(prefix + TAB).Append("}\n");
|
||||
if (isLoad) {
|
||||
sb.Append(prefix + TAB).AppendFormat("return LoadHdiImpl(%s, %s);\n",
|
||||
EmitDescMacroName().c_str(), instName.c_str());
|
||||
} else {
|
||||
sb.Append(prefix + TAB).AppendFormat("UnloadHdiImpl(%s, %s, instance);\n",
|
||||
EmitDescMacroName().c_str(), instName.c_str());
|
||||
sb.Append(prefix + TAB).Append("return;\n");
|
||||
}
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CClientProxyCodeEmitter::EmitUtilMethods(StringBuilder &sb, bool isDecl)
|
||||
{
|
||||
UtilMethodMap methods;
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
|
||||
if (param->GetAttribute() == ASTParamAttr::PARAM_IN) {
|
||||
typeEmitter->EmitCWriteMethods(methods, "", "", isDecl);
|
||||
} else {
|
||||
typeEmitter->EmitCReadMethods(methods, "", "", isDecl);
|
||||
}
|
||||
}
|
||||
}
|
||||
EmitUtilMethodMap(sb, methods);
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
144
idl_tool_2/codegen/HDI/c/c_client_proxy_code_emitter.h
Normal file
144
idl_tool_2/codegen/HDI/c/c_client_proxy_code_emitter.h
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_HDI_C_CLIENT_PROXY_CODE_EMITTER_H
|
||||
#define OHOS_IDL_HDI_C_CLIENT_PROXY_CODE_EMITTER_H
|
||||
|
||||
#include "hdi_c_code_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
class CClientProxyCodeEmitter : public HDICCodeEmitter {
|
||||
public:
|
||||
CClientProxyCodeEmitter() : HDICCodeEmitter() {}
|
||||
|
||||
~CClientProxyCodeEmitter() override = default;
|
||||
|
||||
private:
|
||||
bool ResolveDirectory(const std::string &targetDirectory) override;
|
||||
|
||||
void EmitCode() override;
|
||||
|
||||
void EmitPassthroughProxySourceFile();
|
||||
|
||||
void EmitPassthroughProxyInclusions(StringBuilder &sb);
|
||||
|
||||
void EmitPassthroughGetInstanceMethod(StringBuilder &sb) const;
|
||||
|
||||
void EmitPassthroughReleaseInstanceMethod(StringBuilder &sb) const;
|
||||
|
||||
void EmitProxySourceFile();
|
||||
|
||||
void EmitProxyDefinition(StringBuilder &sb) const;
|
||||
|
||||
void EmitProxyInclusions(StringBuilder &sb);
|
||||
|
||||
void GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const;
|
||||
|
||||
void EmitProxyCallMethodImpl(StringBuilder &sb) const;
|
||||
|
||||
void EmitProxyKernelCallMethodImpl(StringBuilder &sb) const;
|
||||
|
||||
void EmitProxyMethodImpls(StringBuilder &sb);
|
||||
|
||||
void EmitProxyMethodImpl(const AutoPtr<ASTMethod> &method, StringBuilder &sb);
|
||||
|
||||
void EmitProxyMethodBody(const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitCreateBuf(const std::string &dataBufName,
|
||||
const std::string &replyBufName, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitCheckThisPointer(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitWriteInterfaceToken(const std::string &dataBufName, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitWriteFlagOfNeedSetMem(const AutoPtr<ASTMethod> &method,
|
||||
const std::string &dataBufName, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitReleaseBuf(const std::string &dataBufName,
|
||||
const std::string &replyBufName, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitReadProxyMethodParameter(const AutoPtr<ASTParameter> ¶m, const std::string &gotoLabel,
|
||||
StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitStubCallMethod(const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitProxyAsObjectMethodImpl(StringBuilder &sb) const;
|
||||
|
||||
void EmitProxyConstruction(StringBuilder &sb) const;
|
||||
|
||||
void EmitProxyExternalMethodImpl(StringBuilder &sb);
|
||||
|
||||
void EmitKernelProxyExternalMethodImpl(StringBuilder &sb);
|
||||
|
||||
// the get method for getting kernel driver client object
|
||||
void EmitKernelProxyGetMethodImpl(StringBuilder &sb) const;
|
||||
|
||||
void EmitKernelProxyGetInstanceMethodImpl(const std::string &remoteName, StringBuilder &sb) const;
|
||||
|
||||
// the release metod for releasing kernel driver client object
|
||||
void EmitKernelProxyReleaseMethodImpl(const std::string &remoteName, const std::string &recycleFuncName,
|
||||
StringBuilder &sb) const;
|
||||
|
||||
void EmitSerialProxyExternalMethodImpl(StringBuilder &sb);
|
||||
|
||||
// the get method for getting interface object
|
||||
void EmitIfaceProxyGetMethodImpl(const std::string &serMajorName, const std::string &serMinorName,
|
||||
const std::string &remoteName, StringBuilder &sb);
|
||||
|
||||
// the release metod for releasing interface obj
|
||||
void EmitIfaceProxyReleaseMethodImpl(
|
||||
const std::string &remoteName, const std::string &recycleFuncName, StringBuilder &sb) const;
|
||||
|
||||
void EmitCbProxyReleaseMethodImpl(
|
||||
const std::string &remoteName, const std::string &recycleFuncName, StringBuilder &sb) const;
|
||||
|
||||
void EmitProxyExternalMethod(StringBuilder &sb);
|
||||
|
||||
// the get method for getting driver client object
|
||||
void EmitProxyGetMethodImpl(StringBuilder &sb) const;
|
||||
|
||||
void EmitProxyGetInstanceMethodImpl(const std::string &remoteName, const std::string &serviceName,
|
||||
StringBuilder &sb) const;
|
||||
|
||||
void EmitProxyGetRemoteService(const std::string &remoteName,
|
||||
const std::string &serviceName, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitProxySetInterfaceDesc(const std::string &remoteName, const std::string &recycleFuncName,
|
||||
StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitProxyCreateProxyObject(const std::string &clientObjName, const std::string &remoteName,
|
||||
const std::string &recycleFuncName, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitProxyCheckVersion(const std::string &clientObjName, const std::string &serMajorName,
|
||||
const std::string &serMinorName, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
// the release metod for releasing driver client obj
|
||||
void EmitProxyReleaseMethodImpl(StringBuilder &sb) const;
|
||||
|
||||
void EmitProxyReleaseInstanceMethodImpl(const std::string &serviceName, const std::string &remoteName,
|
||||
const std::string &recycleFuncName, StringBuilder &sb);
|
||||
|
||||
void EmitProxyLoadOrUnLoadHdiImpl(const std::string &serviceName, bool isLoad, StringBuilder &sb,
|
||||
const std::string &prefix) const;
|
||||
|
||||
void EmitUtilMethods(StringBuilder &sb, bool isDecl) override;
|
||||
|
||||
std::vector<std::string> freeObjStatements_;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_HDI_C_CLIENT_PROXY_CODE_EMITTER_H
|
537
idl_tool_2/codegen/HDI/c/c_custom_types_code_emitter.cpp
Normal file
537
idl_tool_2/codegen/HDI/c/c_custom_types_code_emitter.cpp
Normal file
@ -0,0 +1,537 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "c_custom_types_code_emitter.h"
|
||||
#include "util/file.h"
|
||||
#include "util/logger.h"
|
||||
#include "util/options.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
bool CCustomTypesCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
|
||||
{
|
||||
if (ast_->GetASTFileType() != ASTFileType::AST_TYPES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
directory_ = GetFileParentPath(targetDirectory);
|
||||
if (!File::CreateParentDir(directory_)) {
|
||||
Logger::E("CCustomTypesCodeEmitter", "Create '%s' failed!", directory_.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitCode()
|
||||
{
|
||||
switch (mode_) {
|
||||
case GenMode::LOW:
|
||||
case GenMode::PASSTHROUGH: {
|
||||
EmitPassthroughCustomTypesHeaderFile();
|
||||
break;
|
||||
}
|
||||
case GenMode::IPC:
|
||||
case GenMode::KERNEL: {
|
||||
EmitCustomTypesHeaderFile();
|
||||
EmitCustomTypesSourceFile();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitPassthroughCustomTypesHeaderFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(baseName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitHeadMacro(sb, baseName_);
|
||||
sb.Append("\n");
|
||||
EmitPassthroughHeaderInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitHeadExternC(sb);
|
||||
sb.Append("\n");
|
||||
EmitCustomTypeDecls(sb);
|
||||
EmitTailExternC(sb);
|
||||
sb.Append("\n");
|
||||
EmitTailMacro(sb, baseName_);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitPassthroughHeaderInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "stdint");
|
||||
headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "stdbool");
|
||||
GetStdlibInclusions(headerFiles);
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitCustomTypesHeaderFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(baseName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitHeadMacro(sb, baseName_);
|
||||
sb.Append("\n");
|
||||
EmitHeaderInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitInterfaceBuffSizeMacro(sb);
|
||||
sb.Append("\n");
|
||||
EmitHeadExternC(sb);
|
||||
sb.Append("\n");
|
||||
EmitForwardDeclaration(sb);
|
||||
sb.Append("\n");
|
||||
EmitCustomTypeDecls(sb);
|
||||
sb.Append("\n");
|
||||
EmitCustomTypeFuncDecl(sb);
|
||||
sb.Append("\n");
|
||||
EmitTailExternC(sb);
|
||||
sb.Append("\n");
|
||||
EmitTailMacro(sb, baseName_);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitHeaderInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "stdint");
|
||||
headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "stdbool");
|
||||
GetStdlibInclusions(headerFiles);
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitForwardDeclaration(StringBuilder &sb) const
|
||||
{
|
||||
sb.Append("struct HdfSBuf;\n");
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitCustomTypeDecls(StringBuilder &sb) const
|
||||
{
|
||||
for (size_t i = 0; i < ast_->GetTypeDefinitionNumber(); i++) {
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(ast_->GetTypeDefintion(i));
|
||||
sb.Append(typeEmitter->EmitCTypeDecl()).Append("\n");
|
||||
if (i + 1 < ast_->GetTypeDefinitionNumber()) {
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitCustomTypeFuncDecl(StringBuilder &sb) const
|
||||
{
|
||||
for (size_t i = 0; i < ast_->GetTypeDefinitionNumber(); i++) {
|
||||
AutoPtr<ASTType> type = ast_->GetTypeDefintion(i);
|
||||
if (type->GetTypeKind() == TypeKind::TYPE_STRUCT) {
|
||||
EmitCustomTypeMarshallFuncDecl(sb, type);
|
||||
if (i + 1 < ast_->GetTypeDefinitionNumber()) {
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitCustomTypeMarshallFuncDecl(StringBuilder &sb, const AutoPtr<ASTType> &type) const
|
||||
{
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
|
||||
std::string objName("dataBlock");
|
||||
sb.AppendFormat("bool %sBlockMarshalling(struct HdfSBuf *data, const %s *%s);\n\n", type->GetName().c_str(),
|
||||
typeEmitter->EmitCType().c_str(), objName.c_str());
|
||||
sb.AppendFormat("bool %sBlockUnmarshalling(struct HdfSBuf *data, %s *%s);\n\n", type->GetName().c_str(),
|
||||
typeEmitter->EmitCType().c_str(), objName.c_str());
|
||||
sb.AppendFormat("void %sFree(%s *%s, bool freeSelf);\n", type->GetName().c_str(),
|
||||
typeEmitter->EmitCType().c_str(), objName.c_str());
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitCustomTypesSourceFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.c", directory_.c_str(), FileName(baseName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitSoucreInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitUtilMethods(sb, true);
|
||||
sb.Append("\n");
|
||||
EmitUtilMethods(sb, false);
|
||||
sb.Append("\n");
|
||||
EmitCustomTypeDataProcess(sb);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitSoucreInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(baseName_));
|
||||
GetSourceOtherLibInclusions(headerFiles);
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
|
||||
{
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_sbuf");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "osal_mem");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitCustomTypeDataProcess(StringBuilder &sb)
|
||||
{
|
||||
for (size_t i = 0; i < ast_->GetTypeDefinitionNumber(); i++) {
|
||||
AutoPtr<ASTType> type = ast_->GetTypeDefintion(i);
|
||||
if (type->GetTypeKind() == TypeKind::TYPE_STRUCT) {
|
||||
AutoPtr<ASTStructType> structType = dynamic_cast<ASTStructType *>(type.Get());
|
||||
EmitCustomTypeMarshallingImpl(sb, structType);
|
||||
EmitCustomTypeUnmarshallingImpl(sb, structType);
|
||||
sb.Append("\n");
|
||||
EmitCustomTypeFreeImpl(sb, structType);
|
||||
if (i + 1 < ast_->GetTypeDefinitionNumber()) {
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitCustomTypeMarshallingImpl(StringBuilder &sb, const AutoPtr<ASTStructType> &type)
|
||||
{
|
||||
std::string typeName = GetTypeEmitter(type.Get())->EmitCType();
|
||||
std::string objName("dataBlock");
|
||||
sb.AppendFormat("bool %sBlockMarshalling(struct HdfSBuf *data, const %s *%s)\n", type->GetName().c_str(),
|
||||
typeName.c_str(), objName.c_str());
|
||||
sb.Append("{\n");
|
||||
EmitMarshallingVarDecl(type, objName, sb, TAB);
|
||||
EmitParamCheck(objName, sb, TAB);
|
||||
sb.Append("\n");
|
||||
if (type->IsPod()) {
|
||||
if (Options::GetInstance().DoGenerateKernelCode()) {
|
||||
sb.Append(TAB).AppendFormat("if (!HdfSbufWriteBuffer(data, (const void *)%s, sizeof(%s))) {\n",
|
||||
objName.c_str(), typeName.c_str());
|
||||
} else {
|
||||
sb.Append(TAB).AppendFormat("if (!HdfSbufWriteUnpadBuffer(data, (const uint8_t *)%s, sizeof(%s))) {\n",
|
||||
objName.c_str(), typeName.c_str());
|
||||
}
|
||||
sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: failed to write buffer data\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return false;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
} else {
|
||||
for (size_t i = 0; i < type->GetMemberNumber(); i++) {
|
||||
std::string memberName = type->GetMemberName(i);
|
||||
std::string name = StringHelper::Format("%s->%s", objName.c_str(), memberName.c_str());
|
||||
GetTypeEmitter(type->GetMemberType(i))->EmitCMarshalling(name, sb, TAB);
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
sb.Append(TAB).Append("return true;\n");
|
||||
sb.Append("}\n\n");
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitCustomTypeUnmarshallingImpl(StringBuilder &sb, const AutoPtr<ASTStructType> &type)
|
||||
{
|
||||
std::string typeName = GetTypeEmitter(type.Get())->EmitCType();
|
||||
std::string objName("dataBlock");
|
||||
freeObjStatements_.clear();
|
||||
sb.AppendFormat("bool %sBlockUnmarshalling(struct HdfSBuf *data, %s *%s)\n", type->GetName().c_str(),
|
||||
typeName.c_str(), objName.c_str());
|
||||
sb.Append("{\n");
|
||||
EmitUnmarshallingVarDecl(type, objName, sb, TAB);
|
||||
EmitParamCheck(objName, sb, TAB);
|
||||
sb.Append("\n");
|
||||
if (type->IsPod()) {
|
||||
EmitPodTypeUnmarshalling(typeName, objName, sb, TAB);
|
||||
} else {
|
||||
for (size_t i = 0; i < type->GetMemberNumber(); i++) {
|
||||
AutoPtr<ASTType> memberType = type->GetMemberType(i);
|
||||
EmitMemberUnmarshalling(memberType, objName, type->GetMemberName(i), sb, TAB);
|
||||
}
|
||||
}
|
||||
sb.Append(TAB).Append("return true;\n");
|
||||
sb.AppendFormat("%s:\n", errorsLabel_ );
|
||||
EmitCustomTypeMemoryRecycle(type, objName, sb, TAB);
|
||||
sb.Append(TAB).Append("return false;\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitMarshallingVarDecl(const AutoPtr<ASTStructType> &type,
|
||||
const std::string &name, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
(void)name;
|
||||
if (!Options::GetInstance().DoGenerateKernelCode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < type->GetMemberNumber(); i++) {
|
||||
if (EmitNeedLoopVar(type->GetMemberType(i), true, false)) {
|
||||
sb.Append(prefix).Append("uint32_t i = 0;\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitUnmarshallingVarDecl(
|
||||
const AutoPtr<ASTStructType> &type, const std::string &name, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
if (!Options::GetInstance().DoGenerateKernelCode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (type->IsPod()) {
|
||||
sb.Append(prefix).AppendFormat("%s *%sPtr = NULL;\n",
|
||||
GetTypeEmitter(type.Get())->EmitCType().c_str(), name.c_str());
|
||||
sb.Append(prefix).AppendFormat("uint32_t %sLen = 0;\n\n", name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < type->GetMemberNumber(); i++) {
|
||||
if (EmitNeedLoopVar(type->GetMemberType(i), true, true)) {
|
||||
sb.Append(prefix).Append("uint32_t i = 0;\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitParamCheck(
|
||||
const std::string &name, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).Append("if (data == NULL) {\n");
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid sbuf\", __func__);\n");
|
||||
sb.Append(prefix + TAB).Append("return false;\n");
|
||||
sb.Append(prefix).Append("}\n\n");
|
||||
sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", name.c_str());
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid data block\", __func__);\n");
|
||||
sb.Append(prefix + TAB).Append("return false;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitPodTypeUnmarshalling(
|
||||
const std::string &typeName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
std::string objPtrName = StringHelper::Format("%sPtr", name.c_str());
|
||||
if (Options::GetInstance().DoGenerateKernelCode()) {
|
||||
std::string lenName = StringHelper::Format("%sLen", name.c_str());
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"if (!HdfSbufReadBuffer(data, (const void**)&%s, &%s)) {\n", objPtrName.c_str(), lenName.c_str());
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read buffer data\", __func__);\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", errorsLabel_ );
|
||||
sb.Append(prefix).Append("}\n\n");
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"if (%s == NULL || %s != sizeof(%s)) {\n", objPtrName.c_str(), lenName.c_str(), typeName.c_str());
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid data from reading buffer\", __func__);\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", errorsLabel_ );
|
||||
sb.Append(prefix).Append("}\n");
|
||||
} else {
|
||||
sb.Append(prefix).AppendFormat("const %s *%s = (const %s *)HdfSbufReadUnpadBuffer(data, sizeof(%s));\n",
|
||||
typeName.c_str(), objPtrName.c_str(), typeName.c_str(), typeName.c_str());
|
||||
sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", objPtrName.c_str());
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to read buffer data\", __func__);\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", errorsLabel_ );
|
||||
sb.Append(prefix).Append("}\n\n");
|
||||
}
|
||||
|
||||
sb.Append(prefix).AppendFormat("if (memcpy_s(%s, sizeof(%s), %s, sizeof(%s)) != EOK) {\n", name.c_str(),
|
||||
typeName.c_str(), objPtrName.c_str(), typeName.c_str());
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to memcpy data\", __func__);\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", errorsLabel_ );
|
||||
sb.Append(prefix).Append("}\n\n");
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitMemberUnmarshalling(const AutoPtr<ASTType> &type, const std::string &name,
|
||||
const std::string &memberName, StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
std::string varName = StringHelper::Format("%s->%s", name.c_str(), memberName.c_str());
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
|
||||
switch (type->GetTypeKind()) {
|
||||
case TypeKind::TYPE_STRING: {
|
||||
EmitStringMemberUnmarshalling(typeEmitter, memberName, varName, sb, prefix);
|
||||
break;
|
||||
}
|
||||
case TypeKind::TYPE_STRUCT: {
|
||||
std::string paramName = StringHelper::Format("&%s", varName.c_str());
|
||||
typeEmitter->EmitCUnMarshalling(paramName, errorsLabel_, sb, prefix, freeObjStatements_);
|
||||
sb.Append("\n");
|
||||
break;
|
||||
}
|
||||
case TypeKind::TYPE_UNION: {
|
||||
std::string tmpName = StringHelper::Format("%sCp", memberName.c_str());
|
||||
typeEmitter->EmitCUnMarshalling(tmpName, errorsLabel_, sb, prefix, freeObjStatements_);
|
||||
sb.Append(prefix).AppendFormat("if (memcpy_s(&%s, sizeof(%s), %s, sizeof(%s)) != EOK) {\n", varName.c_str(),
|
||||
typeEmitter->EmitCType().c_str(), tmpName.c_str(), typeEmitter->EmitCType().c_str());
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: failed to memcpy data\", __func__);\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", errorsLabel_ );
|
||||
sb.Append(prefix).Append("}\n");
|
||||
break;
|
||||
}
|
||||
case TypeKind::TYPE_ARRAY:
|
||||
case TypeKind::TYPE_LIST: {
|
||||
EmitArrayMemberUnmarshalling(type, memberName, varName, sb, prefix);
|
||||
sb.Append("\n");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
typeEmitter->EmitCUnMarshalling(varName, errorsLabel_, sb, prefix, freeObjStatements_);
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitStringMemberUnmarshalling(const AutoPtr<HdiTypeEmitter> &typeEmitter,
|
||||
const std::string &memberName, const std::string &varName, StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
std::string tmpName = StringHelper::Format("%sCp", memberName.c_str());
|
||||
sb.Append(prefix).Append("{\n");
|
||||
typeEmitter->EmitCUnMarshalling(tmpName, errorsLabel_, sb, prefix + TAB, freeObjStatements_);
|
||||
if (Options::GetInstance().DoGenerateKernelCode()) {
|
||||
sb.Append(prefix + TAB)
|
||||
.AppendFormat("%s = (char*)OsalMemCalloc(strlen(%s) + 1);\n", varName.c_str(), tmpName.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("if (%s == NULL) {\n", varName.c_str());
|
||||
sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", errorsLabel_ );
|
||||
sb.Append(prefix + TAB).Append("}\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("if (strcpy_s(%s, (strlen(%s) + 1), %s) != EOK) {\n",
|
||||
varName.c_str(), tmpName.c_str(), tmpName.c_str());
|
||||
sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", errorsLabel_ );
|
||||
sb.Append(prefix + TAB).Append("}\n");
|
||||
} else {
|
||||
sb.Append(prefix + TAB).AppendFormat("%s = strdup(%s);\n", varName.c_str(), tmpName.c_str());
|
||||
}
|
||||
|
||||
sb.Append(prefix + TAB).AppendFormat("if (%s == NULL) {\n", varName.c_str());
|
||||
sb.Append(prefix + TAB + TAB).AppendFormat("goto %s;\n", errorsLabel_ );
|
||||
sb.Append(prefix + TAB).Append("}\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
sb.Append("\n");
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitArrayMemberUnmarshalling(const AutoPtr<ASTType> &type, const std::string &memberName,
|
||||
const std::string &varName, StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
std::string tmpName = StringHelper::Format("%sCp", memberName.c_str());
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
|
||||
AutoPtr<ASTType> elementType = nullptr;
|
||||
if (type->GetTypeKind() == TypeKind::TYPE_ARRAY) {
|
||||
AutoPtr<ASTArrayType> arrayType = dynamic_cast<ASTArrayType *>(type.Get());
|
||||
elementType = arrayType->GetElementType();
|
||||
} else {
|
||||
AutoPtr<ASTListType> listType = dynamic_cast<ASTListType *>(type.Get());
|
||||
elementType = listType->GetElementType();
|
||||
}
|
||||
|
||||
if (elementType->IsStringType()) {
|
||||
typeEmitter->EmitCUnMarshalling(varName, errorsLabel_, sb, prefix, freeObjStatements_);
|
||||
return;
|
||||
}
|
||||
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("%s* %s = NULL;\n",
|
||||
GetTypeEmitter(elementType)->EmitCType().c_str(), tmpName.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("uint32_t %sLen = 0;\n", tmpName.c_str());
|
||||
typeEmitter->EmitCUnMarshalling(tmpName, errorsLabel_, sb, prefix + TAB, freeObjStatements_);
|
||||
sb.Append(prefix + TAB).AppendFormat("%s = %s;\n", varName.c_str(), tmpName.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("%sLen = %sLen;\n", varName.c_str(), tmpName.c_str());
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitCustomTypeFreeImpl(StringBuilder &sb, const AutoPtr<ASTStructType> &type) const
|
||||
{
|
||||
std::string objName("dataBlock");
|
||||
sb.AppendFormat("void %sFree(%s *%s, bool freeSelf)\n", type->GetName().c_str(),
|
||||
GetTypeEmitter(type.Get())->EmitCType().c_str(), objName.c_str());
|
||||
sb.Append("{\n");
|
||||
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
for (size_t i = 0; i < type->GetMemberNumber(); i++) {
|
||||
AutoPtr<ASTType> memberType = type->GetMemberType(i);
|
||||
if (EmitNeedLoopVar(memberType, false, true)) {
|
||||
sb.Append(TAB).Append("uint32_t i = 0;\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", objName.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("return;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
sb.Append("\n");
|
||||
|
||||
EmitCustomTypeMemoryRecycle(type, objName, sb, TAB);
|
||||
|
||||
sb.Append(TAB).Append("if (freeSelf) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("OsalMemFree(dataBlock);\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitCustomTypeMemoryRecycle(
|
||||
const AutoPtr<ASTStructType> &type, const std::string &name, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
for (size_t i = 0; i < type->GetMemberNumber(); i++) {
|
||||
AutoPtr<ASTType> memberType = type->GetMemberType(i);
|
||||
std::string memberName = type->GetMemberName(i);
|
||||
std::string varName = StringHelper::Format("%s->%s", name.c_str(), memberName.c_str());
|
||||
switch (memberType->GetTypeKind()) {
|
||||
case TypeKind::TYPE_STRING:
|
||||
case TypeKind::TYPE_STRUCT:
|
||||
case TypeKind::TYPE_ARRAY:
|
||||
case TypeKind::TYPE_LIST:
|
||||
GetTypeEmitter(memberType)->EmitMemoryRecycle(varName, false, sb, prefix);
|
||||
sb.Append("\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCustomTypesCodeEmitter::EmitUtilMethods(StringBuilder &sb, bool isDecl)
|
||||
{
|
||||
UtilMethodMap methods;
|
||||
for (const auto &typePair : ast_->GetTypes()) {
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(typePair.second);
|
||||
typeEmitter->EmitCWriteMethods(methods, "", "", isDecl);
|
||||
typeEmitter->EmitCStubReadMethods(methods, "", "", isDecl);
|
||||
}
|
||||
EmitUtilMethodMap(sb, methods);
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
98
idl_tool_2/codegen/HDI/c/c_custom_types_code_emitter.h
Normal file
98
idl_tool_2/codegen/HDI/c/c_custom_types_code_emitter.h
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_HDI_C_CUSTOM_TYPES_CODE_EMITTER_H
|
||||
#define OHOS_IDL_HDI_C_CUSTOM_TYPES_CODE_EMITTER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "hdi_c_code_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
class CCustomTypesCodeEmitter : public HDICCodeEmitter {
|
||||
public:
|
||||
CCustomTypesCodeEmitter() : HDICCodeEmitter() {}
|
||||
|
||||
~CCustomTypesCodeEmitter() override = default;
|
||||
|
||||
private:
|
||||
bool ResolveDirectory(const std::string &targetDirectory) override;
|
||||
|
||||
void EmitCode() override;
|
||||
|
||||
void EmitPassthroughCustomTypesHeaderFile();
|
||||
|
||||
void EmitPassthroughHeaderInclusions(StringBuilder &sb);
|
||||
|
||||
void EmitCustomTypesHeaderFile();
|
||||
|
||||
void EmitHeaderInclusions(StringBuilder &sb);
|
||||
|
||||
void EmitForwardDeclaration(StringBuilder &sb) const;
|
||||
|
||||
void EmitCustomTypeDecls(StringBuilder &sb) const;
|
||||
|
||||
void EmitCustomTypeFuncDecl(StringBuilder &sb) const;
|
||||
|
||||
void EmitCustomTypeMarshallFuncDecl(StringBuilder &sb, const AutoPtr<ASTType> &type) const;
|
||||
|
||||
void EmitCustomTypesSourceFile();
|
||||
|
||||
void EmitSoucreInclusions(StringBuilder &sb);
|
||||
|
||||
void GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const;
|
||||
|
||||
void EmitCustomTypeDataProcess(StringBuilder &sb);
|
||||
|
||||
void EmitCustomTypeMarshallingImpl(StringBuilder &sb, const AutoPtr<ASTStructType> &type);
|
||||
|
||||
void EmitCustomTypeUnmarshallingImpl(StringBuilder &sb, const AutoPtr<ASTStructType> &type);
|
||||
|
||||
void EmitMarshallingVarDecl(const AutoPtr<ASTStructType> &type,
|
||||
const std::string &name, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitUnmarshallingVarDecl(const AutoPtr<ASTStructType> &type,
|
||||
const std::string &name, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitParamCheck(const std::string &name, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitPodTypeUnmarshalling(const std::string &typeName,
|
||||
const std::string &name, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitMemberUnmarshalling(const AutoPtr<ASTType> &type, const std::string &name, const std::string &memberName,
|
||||
StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitStringMemberUnmarshalling(const AutoPtr<HdiTypeEmitter> &type, const std::string &memberName,
|
||||
const std::string &varName, StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitArrayMemberUnmarshalling(const AutoPtr<ASTType> &type, const std::string &memberName,
|
||||
const std::string &varName, StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitCustomTypeFreeImpl(StringBuilder &sb, const AutoPtr<ASTStructType> &type) const;
|
||||
|
||||
bool NeedEmitInitVar(const AutoPtr<ASTType> &type, bool needFree);
|
||||
|
||||
void EmitCustomTypeMemoryRecycle(const AutoPtr<ASTStructType> &type,
|
||||
const std::string &name, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitUtilMethods(StringBuilder &sb, bool isDecl) override;
|
||||
|
||||
std::vector<std::string> freeObjStatements_;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_HDI_C_CUSTOM_TYPES_CODE_EMITTER_H
|
291
idl_tool_2/codegen/HDI/c/c_interface_code_emitter.cpp
Normal file
291
idl_tool_2/codegen/HDI/c/c_interface_code_emitter.cpp
Normal file
@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "c_interface_code_emitter.h"
|
||||
#include "util/file.h"
|
||||
#include "util/logger.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
bool CInterfaceCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
|
||||
{
|
||||
if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
|
||||
directory_ = GetFileParentPath(targetDirectory);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!File::CreateParentDir(directory_)) {
|
||||
Logger::E("CInterfaceCodeEmitter", "Create '%s' failed!", directory_.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CInterfaceCodeEmitter::EmitCode()
|
||||
{
|
||||
switch (mode_) {
|
||||
case GenMode::LOW: {
|
||||
EmitLowModeInterfaceHeaderFile();
|
||||
break;
|
||||
}
|
||||
case GenMode::PASSTHROUGH:
|
||||
case GenMode::IPC:
|
||||
case GenMode::KERNEL: {
|
||||
EmitInterfaceHeaderFile();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CInterfaceCodeEmitter::EmitLowModeInterfaceHeaderFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(interfaceName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitHeadMacro(sb, interfaceFullName_);
|
||||
sb.Append("\n");
|
||||
EmitImportInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitHeadExternC(sb);
|
||||
sb.Append("\n");
|
||||
EmitInterfaceVersionMacro(sb);
|
||||
if (!interface_->IsSerializable()) {
|
||||
sb.Append("\n");
|
||||
EmitPreDeclaration(sb);
|
||||
}
|
||||
sb.Append("\n");
|
||||
EmitInterfaceDefinition(sb);
|
||||
if (!interface_->IsSerializable()) {
|
||||
sb.Append("\n");
|
||||
EmitLowModeExternalMethod(sb);
|
||||
}
|
||||
sb.Append("\n");
|
||||
EmitTailExternC(sb);
|
||||
sb.Append("\n");
|
||||
EmitTailMacro(sb, interfaceFullName_);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CInterfaceCodeEmitter::EmitLowModeExternalMethod(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat(
|
||||
"inline struct %s *%sGet(const char *serviceName)\n", interfaceName_.c_str(), interfaceName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).AppendFormat(
|
||||
"return (struct %s *)DevSvcManagerClntGetService(serviceName);\n", interfaceName_.c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CInterfaceCodeEmitter::EmitInterfaceHeaderFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(interfaceName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitHeadMacro(sb, interfaceFullName_);
|
||||
sb.Append("\n");
|
||||
EmitImportInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitHeadExternC(sb);
|
||||
if (!Options::GetInstance().DoPassthrough()) {
|
||||
sb.Append("\n");
|
||||
EmitPreDeclaration(sb);
|
||||
}
|
||||
sb.Append("\n");
|
||||
EmitInterfaceDesc(sb);
|
||||
sb.Append("\n");
|
||||
EmitInterfaceVersionMacro(sb);
|
||||
if (!Options::GetInstance().DoPassthrough()) {
|
||||
sb.Append("\n");
|
||||
EmitInterfaceBuffSizeMacro(sb);
|
||||
sb.Append("\n");
|
||||
EmitInterfaceMethodCommands(sb, "");
|
||||
}
|
||||
sb.Append("\n");
|
||||
EmitInterfaceDefinition(sb);
|
||||
EmitExternalMethod(sb);
|
||||
EmitTailExternC(sb);
|
||||
sb.Append("\n");
|
||||
EmitTailMacro(sb, interfaceFullName_);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CInterfaceCodeEmitter::EmitImportInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
|
||||
GetStdlibInclusions(headerFiles);
|
||||
GetImportInclusions(headerFiles);
|
||||
GetHeaderOtherLibInclusions(headerFiles);
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CInterfaceCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
|
||||
{
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
|
||||
if (!Options::GetInstance().DoGenerateKernelCode()) {
|
||||
headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "stdint");
|
||||
headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "stdbool");
|
||||
}
|
||||
}
|
||||
|
||||
void CInterfaceCodeEmitter::EmitPreDeclaration(StringBuilder &sb) const
|
||||
{
|
||||
sb.Append("struct HdfRemoteService;\n");
|
||||
}
|
||||
|
||||
void CInterfaceCodeEmitter::EmitInterfaceDesc(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("#define %s \"%s\"\n", EmitDescMacroName().c_str(), interfaceFullName_.c_str());
|
||||
}
|
||||
|
||||
void CInterfaceCodeEmitter::EmitInterfaceVersionMacro(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("#define %s %u\n", majorVerName_.c_str(), ast_->GetMajorVer());
|
||||
sb.AppendFormat("#define %s %u\n", minorVerName_.c_str(), ast_->GetMinorVer());
|
||||
}
|
||||
|
||||
void CInterfaceCodeEmitter::EmitInterfaceDefinition(StringBuilder &sb)
|
||||
{
|
||||
sb.AppendFormat("struct %s {\n", interfaceName_.c_str());
|
||||
if (mode_ == GenMode::LOW && !interface_->IsSerializable()) {
|
||||
sb.Append(TAB).Append("struct HdfRemoteService *service;\n\n");
|
||||
}
|
||||
EmitInterfaceMethods(sb, TAB);
|
||||
sb.Append("};\n");
|
||||
}
|
||||
|
||||
void CInterfaceCodeEmitter::EmitInterfaceMethods(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
EmitInterfaceMethod(method, sb, prefix);
|
||||
sb.Append("\n");
|
||||
}
|
||||
|
||||
EmitInterfaceMethod(interface_->GetVersionMethod(), sb, prefix);
|
||||
if (mode_ == GenMode::IPC) {
|
||||
sb.Append("\n");
|
||||
EmitAsObjectMethod(sb, TAB);
|
||||
}
|
||||
}
|
||||
|
||||
void CInterfaceCodeEmitter::EmitInterfaceMethod(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
if (method->GetParameterNumber() == 0) {
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"int32_t (*%s)(struct %s *self);\n", method->GetName().c_str(), interfaceName_.c_str());
|
||||
} else {
|
||||
StringBuilder paramStr;
|
||||
paramStr.Append(prefix).AppendFormat(
|
||||
"int32_t (*%s)(struct %s *self, ", method->GetName().c_str(), interfaceName_.c_str());
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
EmitInterfaceMethodParameter(param, paramStr, "");
|
||||
if (i + 1 < method->GetParameterNumber()) {
|
||||
paramStr.Append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
paramStr.Append(");");
|
||||
sb.Append(SpecificationParam(paramStr, prefix + TAB));
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void CInterfaceCodeEmitter::EmitAsObjectMethod(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("struct HdfRemoteService* (*AsObject)(struct %s *self);\n", interfaceName_.c_str());
|
||||
}
|
||||
|
||||
void CInterfaceCodeEmitter::EmitExternalMethod(StringBuilder &sb) const
|
||||
{
|
||||
if (Options::GetInstance().DoPassthrough() && interface_->IsSerializable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
sb.Append("\n");
|
||||
EmitInterfaceGetMethodDecl(sb);
|
||||
sb.Append("\n");
|
||||
EmitInterfaceReleaseMethodDecl(sb);
|
||||
}
|
||||
|
||||
void CInterfaceCodeEmitter::EmitInterfaceGetMethodDecl(StringBuilder &sb) const
|
||||
{
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
sb.AppendFormat("struct %s *%sGet(void);\n", interfaceName_.c_str(), interfaceName_.c_str());
|
||||
sb.Append("\n");
|
||||
sb.AppendFormat(
|
||||
"struct %s *%sGetInstance(const char *instanceName);\n", interfaceName_.c_str(), interfaceName_.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (interface_->IsSerializable()) {
|
||||
sb.Append("// no external method used to create client object, it only support ipc mode\n");
|
||||
sb.AppendFormat("struct %s *%sGet(struct HdfRemoteService *remote);\n", interfaceName_.c_str(),
|
||||
interfaceName_.c_str());
|
||||
} else {
|
||||
sb.Append("// external method used to create client object, it support ipc and passthrought mode\n");
|
||||
sb.AppendFormat("struct %s *%sGet(bool isStub);\n", interfaceName_.c_str(), interfaceName_.c_str());
|
||||
sb.AppendFormat("struct %s *%sGetInstance(const char *serviceName, bool isStub);\n", interfaceName_.c_str(),
|
||||
interfaceName_.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CInterfaceCodeEmitter::EmitInterfaceReleaseMethodDecl(StringBuilder &sb) const
|
||||
{
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
sb.AppendFormat("void %sRelease(struct %s *instance);\n", interfaceName_.c_str(), interfaceName_.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (interface_->IsCallback()) {
|
||||
sb.Append("// external method used to release client object, it support ipc and passthrought mode\n");
|
||||
sb.AppendFormat("void %sRelease(struct %s *instance);\n", interfaceName_.c_str(),
|
||||
interfaceName_.c_str());
|
||||
} else if (interface_->IsSerializable()) {
|
||||
sb.Append("// external method used to release client object, it support ipc and passthrought mode\n");
|
||||
sb.AppendFormat("void %sRelease(struct %s *instance, bool isStub);\n", interfaceName_.c_str(),
|
||||
interfaceName_.c_str());
|
||||
} else {
|
||||
sb.Append("// external method used to create release object, it support ipc and passthrought mode\n");
|
||||
sb.AppendFormat("void %sRelease(struct %s *instance, bool isStub);\n", interfaceName_.c_str(),
|
||||
interfaceName_.c_str());
|
||||
sb.AppendFormat("void %sReleaseInstance(const char *serviceName, struct %s *instance, bool isStub);\n",
|
||||
interfaceName_.c_str(), interfaceName_.c_str());
|
||||
}
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
67
idl_tool_2/codegen/HDI/c/c_interface_code_emitter.h
Normal file
67
idl_tool_2/codegen/HDI/c/c_interface_code_emitter.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_HDI_C_CLIENT_INTERFACE_CODE_EMITTER_H
|
||||
#define OHOS_IDL_HDI_C_CLIENT_INTERFACE_CODE_EMITTER_H
|
||||
|
||||
#include "hdi_c_code_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
class CInterfaceCodeEmitter : public HDICCodeEmitter {
|
||||
public:
|
||||
CInterfaceCodeEmitter() : HDICCodeEmitter() {}
|
||||
|
||||
~CInterfaceCodeEmitter() override = default;
|
||||
|
||||
private:
|
||||
bool ResolveDirectory(const std::string &targetDirectory) override;
|
||||
|
||||
void EmitCode() override;
|
||||
|
||||
void EmitLowModeInterfaceHeaderFile();
|
||||
|
||||
void EmitLowModeExternalMethod(StringBuilder &sb) const;
|
||||
|
||||
void EmitInterfaceHeaderFile();
|
||||
|
||||
void EmitImportInclusions(StringBuilder &sb);
|
||||
|
||||
void GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const;
|
||||
|
||||
void EmitPreDeclaration(StringBuilder &sb) const;
|
||||
|
||||
void EmitInterfaceDesc(StringBuilder &sb) const;
|
||||
|
||||
void EmitInterfaceVersionMacro(StringBuilder &sb) const;
|
||||
|
||||
void EmitInterfaceDefinition(StringBuilder &sb);
|
||||
|
||||
void EmitInterfaceMethods(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitInterfaceMethod(const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitAsObjectMethod(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitExternalMethod(StringBuilder &sb) const;
|
||||
|
||||
void EmitInterfaceGetMethodDecl(StringBuilder &sb) const;
|
||||
|
||||
void EmitInterfaceReleaseMethodDecl(StringBuilder &sb) const;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_HDI_C_CLIENT_INTERFACE_CODE_EMITTER_H
|
403
idl_tool_2/codegen/HDI/c/c_service_driver_code_emitter.cpp
Normal file
403
idl_tool_2/codegen/HDI/c/c_service_driver_code_emitter.cpp
Normal file
@ -0,0 +1,403 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "c_service_driver_code_emitter.h"
|
||||
#include "util/file.h"
|
||||
#include "util/logger.h"
|
||||
#include "util/options.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
CServiceDriverCodeEmitter::CServiceDriverCodeEmitter() : HDICCodeEmitter(), hostName_("host")
|
||||
{
|
||||
}
|
||||
|
||||
bool CServiceDriverCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
|
||||
{
|
||||
if (ast_->GetASTFileType() != ASTFileType::AST_IFACE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
directory_ = GetFileParentPath(targetDirectory);
|
||||
if (!File::CreateParentDir(directory_)) {
|
||||
Logger::E("CServiceDriverCodeEmitter", "Create '%s' failed!", directory_.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CServiceDriverCodeEmitter::EmitCode()
|
||||
{
|
||||
switch (mode_) {
|
||||
case GenMode::LOW: {
|
||||
EmitLowDriverSourceFile();
|
||||
break;
|
||||
}
|
||||
case GenMode::IPC: {
|
||||
if (!interface_->IsSerializable()) {
|
||||
EmitDriverSourceFile();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GenMode::KERNEL: {
|
||||
EmitDriverSourceFile();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceDriverCodeEmitter::EmitLowDriverSourceFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.c", directory_.c_str(), FileName(baseName_ + "Driver").c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
sb.Append("\n");
|
||||
EmitLowDriverInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitLogTagMacro(sb, FileName(baseName_ + "Driver"));
|
||||
sb.Append("\n");
|
||||
EmitLowDriverBind(sb);
|
||||
sb.Append("\n");
|
||||
EmitDriverInit(sb);
|
||||
sb.Append("\n");
|
||||
EmitLowDriverRelease(sb);
|
||||
sb.Append("\n");
|
||||
EmitDriverEntryDefinition(sb);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CServiceDriverCodeEmitter::EmitLowDriverInclusions(StringBuilder &sb) const
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(implName_));
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_device_desc");
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceDriverCodeEmitter::EmitLowDriverBind(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("static int Hdf%sDriverBind(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("HDF_LOGI(\"%s: driver bind start\", __func__);\n");
|
||||
sb.Append(TAB).AppendFormat("struct %s *serviceImpl = %sGet();\n", implName_.c_str(), implName_.c_str());
|
||||
sb.Append(TAB).Append("if (serviceImpl == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%s: failed to get service impl\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return HDF_FAILURE;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
sb.Append(TAB).Append("deviceObject->service = &serviceImpl->super.service;\n");
|
||||
sb.Append(TAB).Append("return HDF_SUCCESS;\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceDriverCodeEmitter::EmitLowDriverRelease(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("static void Hdf%sDriverRelease(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("HDF_LOGI(\"%s: driver release start\", __func__);\n");
|
||||
|
||||
sb.Append(TAB).Append("if (deviceObject == NULL || deviceObject->service == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%s: invalid device object\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
sb.Append(TAB).AppendFormat(
|
||||
"struct %s *serviceImpl = (struct %s *)deviceObject->service;\n", implName_.c_str(), implName_.c_str());
|
||||
sb.Append(TAB).Append("if (serviceImpl != NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("%sRelease(serviceImpl);\n", implName_.c_str());
|
||||
sb.Append(TAB).Append("}\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceDriverCodeEmitter::EmitDriverSourceFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.c", directory_.c_str(), FileName(baseName_ + "Driver").c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitDriverInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitLogTagMacro(sb, FileName(baseName_ + "Driver"));
|
||||
sb.Append("\n");
|
||||
EmitDriverServiceDecl(sb);
|
||||
sb.Append("\n");
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
EmitKernelDriverDispatch(sb);
|
||||
sb.Append("\n");
|
||||
EmitDriverInit(sb);
|
||||
sb.Append("\n");
|
||||
EmitKernelDriverBind(sb);
|
||||
sb.Append("\n");
|
||||
EmitKernelDriverRelease(sb);
|
||||
} else {
|
||||
EmitDriverDispatch(sb);
|
||||
sb.Append("\n");
|
||||
EmitDriverInit(sb);
|
||||
sb.Append("\n");
|
||||
EmitDriverBind(sb);
|
||||
sb.Append("\n");
|
||||
EmitDriverRelease(sb);
|
||||
}
|
||||
sb.Append("\n");
|
||||
EmitDriverEntryDefinition(sb);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CServiceDriverCodeEmitter::EmitDriverInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(implName_));
|
||||
} else {
|
||||
headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
|
||||
}
|
||||
|
||||
GetDriverSourceOtherLibInclusions(headerFiles);
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceDriverCodeEmitter::GetDriverSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
|
||||
{
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "osal_mem");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_device_desc");
|
||||
if (mode_ != GenMode::KERNEL) {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_device_object");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_remote_service");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "stub_collector");
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceDriverCodeEmitter::EmitDriverServiceDecl(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("struct Hdf%sHost {\n", baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("struct IDeviceIoService ioService;\n");
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
sb.Append(TAB).AppendFormat("struct %s *service;\n", implName_.c_str());
|
||||
} else {
|
||||
sb.Append(TAB).AppendFormat("struct %s *service;\n", interfaceName_.c_str());
|
||||
sb.Append(TAB).Append("struct HdfRemoteService **stubObject;\n");
|
||||
}
|
||||
sb.Append("};\n");
|
||||
}
|
||||
|
||||
void CServiceDriverCodeEmitter::EmitKernelDriverDispatch(StringBuilder &sb)
|
||||
{
|
||||
sb.AppendFormat(
|
||||
"static int32_t %sDriverDispatch(struct HdfDeviceIoClient *client, int cmdId,\n", baseName_.c_str());
|
||||
sb.Append(TAB).Append("struct HdfSBuf *data, struct HdfSBuf *reply)\n");
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(\n", baseName_.c_str(), hostName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat(
|
||||
"client->device->service, struct Hdf%sHost, ioService);\n", baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("if (%s->service == NULL || %s->service->stub.OnRemoteRequest == NULL) {\n",
|
||||
hostName_.c_str(), hostName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: invalid service obj\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
sb.Append(TAB).AppendFormat("return %s->service->stub.OnRemoteRequest(", hostName_.c_str());
|
||||
sb.AppendFormat("&%s->service->stub.interface, cmdId, data, reply);\n", hostName_.c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceDriverCodeEmitter::EmitDriverDispatch(StringBuilder &sb)
|
||||
{
|
||||
sb.AppendFormat(
|
||||
"static int32_t %sDriverDispatch(struct HdfDeviceIoClient *client, int cmdId,\n", baseName_.c_str());
|
||||
sb.Append(TAB).Append("struct HdfSBuf *data, struct HdfSBuf *reply)\n");
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(", baseName_.c_str(), hostName_.c_str());
|
||||
sb.AppendFormat("client->device->service, struct Hdf%sHost, ioService);\n", baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("if (%s->service == NULL || %s->stubObject == NULL) {\n",
|
||||
hostName_.c_str(), hostName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: invalid service obj\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
sb.Append(TAB).AppendFormat("struct HdfRemoteService *stubObj = *%s->stubObject;\n", hostName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("if (stubObj == NULL || stubObj->dispatcher == NULL || ");
|
||||
sb.Append("stubObj->dispatcher->Dispatch == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
sb.Append(TAB).Append("return stubObj->dispatcher->Dispatch(");
|
||||
sb.Append("(struct HdfRemoteService *)stubObj->target, cmdId, data, reply);\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceDriverCodeEmitter::EmitDriverInit(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("static int Hdf%sDriverInit(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
|
||||
sb.Append("{\n");
|
||||
if (mode_ == GenMode::LOW) {
|
||||
sb.Append(TAB).Append("HDF_LOGI(\"%s: driver init start\", __func__);\n");
|
||||
} else {
|
||||
sb.Append(TAB).Append("HDF_LOGI(\"%{public}s: driver init start\", __func__);\n");
|
||||
}
|
||||
sb.Append(TAB).Append("return HDF_SUCCESS;\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceDriverCodeEmitter::EmitKernelDriverBind(StringBuilder &sb)
|
||||
{
|
||||
sb.AppendFormat("static int Hdf%sDriverBind(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("HDF_LOGI(\"%{public}s: driver bind start\", __func__);\n");
|
||||
sb.Append("\n");
|
||||
|
||||
sb.Append(TAB).AppendFormat("struct Hdf%sHost *%s = (struct Hdf%sHost *)OsalMemCalloc(", baseName_.c_str(),
|
||||
hostName_.c_str(), baseName_.c_str());
|
||||
sb.AppendFormat("sizeof(struct Hdf%sHost));\n", baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", hostName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat(
|
||||
"HDF_LOGE(\"Hdf%sDriverBind create Hdf%sHost object failed!\");\n", baseName_.c_str(), baseName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("return HDF_FAILURE;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
sb.Append("\n");
|
||||
sb.Append(TAB).AppendFormat("%s->ioService.Dispatch = %sDriverDispatch;\n", hostName_.c_str(), baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("%s->ioService.Open = NULL;\n", hostName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("%s->ioService.Release = NULL;\n", hostName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("%s->service = %sServiceGet();\n", hostName_.c_str(), baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("if (%s->service == NULL) {\n", hostName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("OsalMemFree(%s);\n", hostName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: failed to get service object\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return HDF_FAILURE;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
sb.Append("\n");
|
||||
sb.Append(TAB).AppendFormat("deviceObject->service = &%s->ioService;\n", hostName_.c_str());
|
||||
sb.Append(TAB).Append("return HDF_SUCCESS;\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceDriverCodeEmitter::EmitDriverBind(StringBuilder &sb)
|
||||
{
|
||||
sb.AppendFormat("static int Hdf%sDriverBind(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("HDF_LOGI(\"%{public}s: driver bind start\", __func__);\n");
|
||||
sb.Append(TAB).AppendFormat("int32_t ret = HdfDeviceObjectSetInterfaceDesc(deviceObject, %s);\n",
|
||||
EmitDescMacroName().c_str());
|
||||
sb.Append(TAB).Append("if (ret != HDF_SUCCESS) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append(
|
||||
"HDF_LOGE(\"%{public}s: failed to set interface descriptor of device object\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return ret;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
|
||||
sb.Append(TAB).AppendFormat("struct Hdf%sHost *%s = (struct Hdf%sHost *)OsalMemCalloc(", baseName_.c_str(),
|
||||
hostName_.c_str(), baseName_.c_str());
|
||||
sb.AppendFormat("sizeof(struct Hdf%sHost));\n", baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", hostName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("HDF_LOGE(\"%%{public}s: create Hdf%sHost object failed!\", __func__);\n",
|
||||
baseName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("return HDF_FAILURE;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
sb.Append(TAB).AppendFormat("struct %s *serviceImpl = %sGet(true);\n", interfaceName_.c_str(),
|
||||
interfaceName_.c_str());
|
||||
sb.Append(TAB).Append("if (serviceImpl == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: create serviceImpl failed!\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("OsalMemFree(%s);\n", hostName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("return HDF_FAILURE;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
sb.Append(TAB).AppendFormat("struct HdfRemoteService **stubObj = StubCollectorGetOrNewObject(");
|
||||
sb.AppendFormat("%s, serviceImpl);\n", EmitDescMacroName().c_str());
|
||||
sb.Append(TAB).Append("if (stubObj == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: failed to get stub object\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("OsalMemFree(%s);\n", hostName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("%sRelease(serviceImpl, true);\n", interfaceName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("return HDF_FAILURE;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
|
||||
sb.Append(TAB).AppendFormat("%s->ioService.Dispatch = %sDriverDispatch;\n", hostName_.c_str(), baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("%s->ioService.Open = NULL;\n", hostName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("%s->ioService.Release = NULL;\n", hostName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("%s->service = serviceImpl;\n", hostName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("%s->stubObject = stubObj;\n", hostName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("deviceObject->service = &%s->ioService;\n", hostName_.c_str());
|
||||
sb.Append(TAB).Append("return HDF_SUCCESS;\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceDriverCodeEmitter::EmitKernelDriverRelease(StringBuilder &sb)
|
||||
{
|
||||
sb.AppendFormat("static void Hdf%sDriverRelease(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).AppendFormat("HDF_LOGI(\"Hdf%sDriverRelease enter.\");\n", baseName_.c_str());
|
||||
sb.Append(TAB).Append("HDF_LOGI(\"%{public}s: driver release start\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
sb.Append(TAB).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(", baseName_.c_str(), hostName_.c_str());
|
||||
sb.AppendFormat("deviceObject->service, struct Hdf%sHost, ioService);\n", baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("if (%s != NULL) {\n", hostName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("%sServiceRelease(%s->service);\n", baseName_.c_str(), hostName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("OsalMemFree(%s);\n", hostName_.c_str());
|
||||
sb.Append(TAB).Append("}\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceDriverCodeEmitter::EmitDriverRelease(StringBuilder &sb)
|
||||
{
|
||||
sb.AppendFormat("static void Hdf%sDriverRelease(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("HDF_LOGI(\"%{public}s: driver release start\", __func__);\n");
|
||||
|
||||
sb.Append(TAB).Append("if (deviceObject->service == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
|
||||
sb.Append(TAB).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(", baseName_.c_str(), hostName_.c_str());
|
||||
sb.AppendFormat("deviceObject->service, struct Hdf%sHost, ioService);\n", baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("if (%s != NULL) {\n", hostName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("StubCollectorRemoveObject(%s, %s->service);\n",
|
||||
EmitDescMacroName().c_str(), hostName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("%sRelease(%s->service, true);\n", interfaceName_.c_str(),
|
||||
hostName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("OsalMemFree(%s);\n", hostName_.c_str());
|
||||
sb.Append(TAB).Append("}\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceDriverCodeEmitter::EmitDriverEntryDefinition(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("struct HdfDriverEntry g_%sDriverEntry = {\n", StringHelper::StrToLower(baseName_).c_str());
|
||||
sb.Append(TAB).Append(".moduleVersion = 1,\n");
|
||||
sb.Append(TAB).AppendFormat(".moduleName = \"%s\",\n", Options::GetInstance().GetPackage().c_str());
|
||||
sb.Append(TAB).AppendFormat(".Bind = Hdf%sDriverBind,\n", baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat(".Init = Hdf%sDriverInit,\n", baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat(".Release = Hdf%sDriverRelease,\n", baseName_.c_str());
|
||||
sb.Append("};\n\n");
|
||||
sb.AppendFormat("HDF_INIT(g_%sDriverEntry);\n", StringHelper::StrToLower(baseName_).c_str());
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
71
idl_tool_2/codegen/HDI/c/c_service_driver_code_emitter.h
Normal file
71
idl_tool_2/codegen/HDI/c/c_service_driver_code_emitter.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_HDI_C_SERVICE_DRIVER_CODE_EMITTER_H
|
||||
#define OHOS_IDL_HDI_C_SERVICE_DRIVER_CODE_EMITTER_H
|
||||
|
||||
#include "hdi_c_code_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
class CServiceDriverCodeEmitter : public HDICCodeEmitter {
|
||||
public:
|
||||
CServiceDriverCodeEmitter();
|
||||
|
||||
~CServiceDriverCodeEmitter() override = default;
|
||||
|
||||
private:
|
||||
bool ResolveDirectory(const std::string &targetDirectory) override;
|
||||
|
||||
void EmitCode() override;
|
||||
|
||||
void EmitLowDriverSourceFile();
|
||||
|
||||
void EmitLowDriverInclusions(StringBuilder &sb) const;
|
||||
|
||||
void EmitLowDriverBind(StringBuilder &sb) const;
|
||||
|
||||
void EmitLowDriverRelease(StringBuilder &sb) const;
|
||||
|
||||
void EmitDriverSourceFile();
|
||||
|
||||
void EmitDriverInclusions(StringBuilder &sb);
|
||||
|
||||
void GetDriverSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const;
|
||||
|
||||
void EmitDriverServiceDecl(StringBuilder &sb) const;
|
||||
|
||||
void EmitKernelDriverDispatch(StringBuilder &sb);
|
||||
|
||||
void EmitDriverDispatch(StringBuilder &sb);
|
||||
|
||||
void EmitDriverInit(StringBuilder &sb) const;
|
||||
|
||||
void EmitKernelDriverBind(StringBuilder &sb);
|
||||
|
||||
void EmitDriverBind(StringBuilder &sb);
|
||||
|
||||
void EmitKernelDriverRelease(StringBuilder &sb);
|
||||
|
||||
void EmitDriverRelease(StringBuilder &sb);
|
||||
|
||||
void EmitDriverEntryDefinition(StringBuilder &sb) const;
|
||||
private:
|
||||
std::string hostName_;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_HDI_C_SERVICE_DRIVER_CODE_EMITTER_H
|
442
idl_tool_2/codegen/HDI/c/c_service_impl_code_emitter.cpp
Normal file
442
idl_tool_2/codegen/HDI/c/c_service_impl_code_emitter.cpp
Normal file
@ -0,0 +1,442 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "c_service_impl_code_emitter.h"
|
||||
#include "util/file.h"
|
||||
#include "util/logger.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
bool CServiceImplCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
|
||||
{
|
||||
if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
|
||||
directory_ = GetFileParentPath(targetDirectory);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!File::CreateParentDir(directory_)) {
|
||||
Logger::E("CServiceImplCodeEmitter", "Create '%s' failed!", directory_.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitCode()
|
||||
{
|
||||
switch (mode_) {
|
||||
case GenMode::LOW: {
|
||||
EmitLowServiceImplHeaderFile();
|
||||
EmitLowServiceImplSourceFile();
|
||||
break;
|
||||
}
|
||||
case GenMode::PASSTHROUGH:
|
||||
case GenMode::IPC: {
|
||||
if (interface_->IsSerializable()) {
|
||||
EmitServiceImplHeaderFile();
|
||||
}
|
||||
EmitServiceImplSourceFile();
|
||||
break;
|
||||
}
|
||||
case GenMode::KERNEL: {
|
||||
EmitServiceImplHeaderFile();
|
||||
EmitServiceImplSourceFile();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitLowServiceImplHeaderFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(implName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
sb.Append("\n");
|
||||
EmitLicense(sb);
|
||||
EmitHeadMacro(sb, implFullName_);
|
||||
EmitLowServiceImplInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitHeadExternC(sb);
|
||||
sb.Append("\n");
|
||||
EmitLowServiceImplDefinition(sb);
|
||||
sb.Append("\n");
|
||||
EmitServiceImplExternalMethodsDecl(sb);
|
||||
sb.Append("\n");
|
||||
EmitTailExternC(sb);
|
||||
sb.Append("\n");
|
||||
EmitTailMacro(sb, implFullName_);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitLowServiceImplInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitLowServiceImplDefinition(StringBuilder &sb)
|
||||
{
|
||||
sb.AppendFormat("struct %s {\n", implName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("struct %s super;\n", interfaceName_.c_str());
|
||||
sb.Append(TAB).Append("// please add private data here\n");
|
||||
sb.Append("};\n");
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitLowServiceImplSourceFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.c", directory_.c_str(), FileName(implName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitServiceImplSourceInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitLogTagMacro(sb, FileName(implName_));
|
||||
sb.Append("\n");
|
||||
EmitServiceImplMethodImpls(sb, "");
|
||||
sb.Append("\n");
|
||||
EmitLowServiceImplGetMethod(sb);
|
||||
sb.Append("\n");
|
||||
EmitServiceImplReleaseMethod(sb);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitLowServiceImplGetMethod(StringBuilder &sb)
|
||||
{
|
||||
sb.AppendFormat("struct %s *%sServiceGet(void)\n", implName_.c_str(), baseName_.c_str());
|
||||
sb.Append("{\n");
|
||||
|
||||
sb.Append(TAB).AppendFormat("struct %s *service = (struct %s *)OsalMemCalloc(sizeof(struct %s));\n",
|
||||
implName_.c_str(), implName_.c_str(), implName_.c_str());
|
||||
sb.Append(TAB).Append("if (service == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%s: failed to malloc service object\", __func__);\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
sb.Append(TAB).AppendFormat("service->super.%s = %s%s;\n", method->GetName().c_str(),
|
||||
baseName_.c_str(), method->GetName().c_str());
|
||||
}
|
||||
|
||||
AutoPtr<ASTMethod> method = interface_->GetVersionMethod();
|
||||
sb.Append(TAB).AppendFormat("service->super.%s = %s%s;\n", method->GetName().c_str(),
|
||||
baseName_.c_str(), method->GetName().c_str());
|
||||
|
||||
sb.Append(TAB).Append("return service;\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitServiceImplHeaderFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(baseName_ + "Service").c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitHeadMacro(sb, implFullName_);
|
||||
sb.Append("\n");
|
||||
EmitServiceImplHeaderInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitHeadExternC(sb);
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
sb.Append("\n");
|
||||
EmitKernelServiceImplDef(sb);
|
||||
} else if (interface_->IsSerializable()) {
|
||||
sb.Append("\n");
|
||||
EmitServiceImplDef(sb);
|
||||
}
|
||||
sb.Append("\n");
|
||||
EmitServiceImplExternalMethodsDecl(sb);
|
||||
sb.Append("\n");
|
||||
EmitTailExternC(sb);
|
||||
sb.Append("\n");
|
||||
EmitTailMacro(sb, implFullName_);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitServiceImplHeaderInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(stubName_));
|
||||
} else {
|
||||
headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
|
||||
}
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitServiceImplExternalMethodsDecl(StringBuilder &sb) const
|
||||
{
|
||||
std::string instTypeName;
|
||||
if (mode_ == GenMode::LOW || mode_ == GenMode::KERNEL) {
|
||||
instTypeName = implName_;
|
||||
} else {
|
||||
instTypeName = interface_->IsSerializable() ? interfaceName_ : implName_;
|
||||
}
|
||||
sb.AppendFormat("struct %s *%sServiceGet(void);\n\n", instTypeName.c_str(), baseName_.c_str());
|
||||
sb.AppendFormat("void %sServiceRelease(struct %s *instance);\n", baseName_.c_str(), instTypeName.c_str());
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitServiceImplSourceFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.c", directory_.c_str(), FileName(implName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitServiceImplSourceInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitLogTagMacro(sb, FileName(implName_));
|
||||
if (mode_ != GenMode::KERNEL && !interface_->IsSerializable()) {
|
||||
sb.Append("\n");
|
||||
EmitServiceImplDef(sb);
|
||||
}
|
||||
|
||||
sb.Append("\n");
|
||||
EmitServiceImplMethodImpls(sb, "");
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
sb.Append("\n");
|
||||
EmitKernelServiceImplGetMethod(sb);
|
||||
sb.Append("\n");
|
||||
EmitKernelServiceImplReleaseMethod(sb);
|
||||
} else {
|
||||
sb.Append("\n");
|
||||
EmitServiceImplGetMethod(sb);
|
||||
sb.Append("\n");
|
||||
EmitServiceImplReleaseMethod(sb);
|
||||
}
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitServiceImplSourceInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
|
||||
if (mode_ == GenMode::KERNEL || mode_ == GenMode::LOW || interface_->IsSerializable()) {
|
||||
headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(implName_));
|
||||
} else {
|
||||
headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
|
||||
}
|
||||
GetSourceOtherLibInclusions(headerFiles);
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
|
||||
{
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "osal_mem");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitKernelServiceImplDef(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("struct %sService {\n", baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("struct %sStub stub;\n\n", baseName_.c_str());
|
||||
sb.Append(TAB).Append("// please add private data here\n");
|
||||
sb.Append("};\n");
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitServiceImplDef(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("struct %sService {\n", baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("struct %s interface;\n", interfaceName_.c_str());
|
||||
sb.Append("};\n");
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitServiceImplMethodImpls(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
EmitServiceImplMethodImpl(method, sb, prefix);
|
||||
sb.Append("\n");
|
||||
}
|
||||
|
||||
EmitServiceImplGetVersionMethod(sb, prefix);
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitServiceImplMethodImpl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
if (method->GetParameterNumber() == 0) {
|
||||
sb.Append(prefix).AppendFormat("static int32_t %s%s(struct %s *self)\n", baseName_.c_str(),
|
||||
method->GetName().c_str(), interfaceName_.c_str());
|
||||
} else {
|
||||
StringBuilder paramStr;
|
||||
paramStr.Append(prefix).AppendFormat("static int32_t %s%s(struct %s *self, ", baseName_.c_str(),
|
||||
method->GetName().c_str(), interfaceName_.c_str());
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
EmitInterfaceMethodParameter(param, paramStr, "");
|
||||
if (i + 1 < method->GetParameterNumber()) {
|
||||
paramStr.Append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
paramStr.Append(")");
|
||||
sb.Append(SpecificationParam(paramStr, prefix + TAB));
|
||||
sb.Append("\n");
|
||||
}
|
||||
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB).Append("return HDF_SUCCESS;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitServiceImplGetVersionMethod(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
AutoPtr<ASTMethod> method = interface_->GetVersionMethod();
|
||||
sb.Append(prefix).AppendFormat("static int32_t %s%s(struct %s *self, ", baseName_.c_str(),
|
||||
method->GetName().c_str(), interfaceName_.c_str());
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
EmitInterfaceMethodParameter(param, sb, "");
|
||||
if (i + 1 < method->GetParameterNumber()) {
|
||||
sb.Append(", ");
|
||||
}
|
||||
}
|
||||
sb.Append(")\n");
|
||||
sb.Append(prefix).Append("{\n");
|
||||
AutoPtr<ASTParameter> majorParam = method->GetParameter(0);
|
||||
sb.Append(prefix + TAB).AppendFormat("*%s = %s;\n", majorParam->GetName().c_str(), majorVerName_.c_str());
|
||||
AutoPtr<ASTParameter> minorParam = method->GetParameter(1);
|
||||
sb.Append(prefix + TAB).AppendFormat("*%s = %s;\n", minorParam->GetName().c_str(), minorVerName_.c_str());
|
||||
sb.Append(prefix + TAB).Append("return HDF_SUCCESS;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitKernelServiceImplGetMethod(StringBuilder &sb) const
|
||||
{
|
||||
std::string objName = "service";
|
||||
sb.AppendFormat("struct %s *%sGet(void)\n", implName_.c_str(), implName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).AppendFormat("struct %s *%s = (struct %s *)OsalMemCalloc(sizeof(struct %s));\n",
|
||||
implName_.c_str(), objName.c_str(), implName_.c_str(), implName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", objName.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat(
|
||||
"HDF_LOGE(\"%%{public}s: malloc %s obj failed!\", __func__);\n", implName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("return NULL;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
sb.Append(TAB).AppendFormat("if (!%sStubConstruct(&%s->stub)) {\n", baseName_.c_str(), objName.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat(
|
||||
"HDF_LOGE(\"%%{public}s: construct %sStub obj failed!\", __func__);\n", baseName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("OsalMemFree(%s);\n", objName.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("return NULL;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
sb.Append(TAB).AppendFormat("%s->stub.interface.%s = %s%s;\n", objName.c_str(), method->GetName().c_str(),
|
||||
baseName_.c_str(), method->GetName().c_str());
|
||||
}
|
||||
|
||||
sb.Append(TAB).AppendFormat("return service;\n", objName.c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitServiceImplGetMethod(StringBuilder &sb) const
|
||||
{
|
||||
std::string objName = "service";
|
||||
if (interface_->IsSerializable()) {
|
||||
sb.AppendFormat("struct %s *%sServiceGet(void)\n", interfaceName_.c_str(), baseName_.c_str());
|
||||
} else {
|
||||
sb.AppendFormat("struct %s *%sImplGetInstance(void)\n", interfaceName_.c_str(), baseName_.c_str());
|
||||
}
|
||||
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).AppendFormat("struct %s *%s = (struct %s *)OsalMemCalloc(sizeof(struct %s));\n",
|
||||
implName_.c_str(), objName.c_str(), implName_.c_str(), implName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", objName.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat(
|
||||
"HDF_LOGE(\"%%{public}s: malloc %s obj failed!\", __func__);\n", implName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("return NULL;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
sb.Append(TAB).AppendFormat("%s->interface.%s = %s%s;\n", objName.c_str(), method->GetName().c_str(),
|
||||
baseName_.c_str(), method->GetName().c_str());
|
||||
}
|
||||
|
||||
AutoPtr<ASTMethod> method = interface_->GetVersionMethod();
|
||||
sb.Append(TAB).AppendFormat("%s->interface.%s = %s%s;\n", objName.c_str(), method->GetName().c_str(),
|
||||
baseName_.c_str(), method->GetName().c_str());
|
||||
|
||||
sb.Append(TAB).AppendFormat("return &%s->interface;\n", objName.c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitKernelServiceImplReleaseMethod(StringBuilder &sb) const
|
||||
{
|
||||
std::string instName = "instance";
|
||||
sb.AppendFormat(
|
||||
"void %sRelease(struct %s *%s)\n", implName_.c_str(), implName_.c_str(), instName.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", instName.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("return;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
sb.Append(TAB).AppendFormat("OsalMemFree(%s);\n", instName.c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceImplCodeEmitter::EmitServiceImplReleaseMethod(StringBuilder &sb) const
|
||||
{
|
||||
if (mode_ == GenMode::LOW || mode_ == GenMode::KERNEL) {
|
||||
sb.AppendFormat("void %sRelease(struct %s *instance)\n", implName_.c_str(), implName_.c_str());
|
||||
} else {
|
||||
if (interface_->IsSerializable()) {
|
||||
sb.AppendFormat("void %sServiceRelease(struct %s *instance)\n", baseName_.c_str(), interfaceName_.c_str());
|
||||
} else {
|
||||
sb.AppendFormat("void %sImplRelease(struct %s *instance)\n", baseName_.c_str(), interfaceName_.c_str());
|
||||
}
|
||||
}
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("if (instance == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
sb.Append(TAB).Append("OsalMemFree(instance);\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
81
idl_tool_2/codegen/HDI/c/c_service_impl_code_emitter.h
Normal file
81
idl_tool_2/codegen/HDI/c/c_service_impl_code_emitter.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_HDI_C_SERVICE_IMPL_CODE_EMITTER_H
|
||||
#define OHOS_IDL_HDI_C_SERVICE_IMPL_CODE_EMITTER_H
|
||||
|
||||
#include "hdi_c_code_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
class CServiceImplCodeEmitter : public HDICCodeEmitter {
|
||||
public:
|
||||
CServiceImplCodeEmitter() : HDICCodeEmitter() {}
|
||||
|
||||
~CServiceImplCodeEmitter() override = default;
|
||||
|
||||
private:
|
||||
bool ResolveDirectory(const std::string &targetDirectory) override;
|
||||
|
||||
void EmitCode() override;
|
||||
|
||||
// generate service header file of low mode
|
||||
void EmitLowServiceImplHeaderFile();
|
||||
|
||||
void EmitLowServiceImplInclusions(StringBuilder &sb);
|
||||
|
||||
void EmitLowServiceImplDefinition(StringBuilder &sb);
|
||||
|
||||
// generate service source file of low mode
|
||||
void EmitLowServiceImplSourceFile();
|
||||
|
||||
void EmitLowServiceImplGetMethod(StringBuilder &sb);
|
||||
|
||||
// generate service header file of ipc, passthrough, kernel mode
|
||||
void EmitServiceImplHeaderFile();
|
||||
|
||||
void EmitServiceImplHeaderInclusions(StringBuilder &sb);
|
||||
|
||||
void EmitServiceImplExternalMethodsDecl(StringBuilder &sb) const;
|
||||
|
||||
void EmitServiceImplSourceFile();
|
||||
|
||||
void EmitServiceImplSourceInclusions(StringBuilder &sb);
|
||||
|
||||
void GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const;
|
||||
|
||||
void EmitKernelServiceImplDef(StringBuilder &sb) const;
|
||||
|
||||
void EmitServiceImplDef(StringBuilder &sb) const;
|
||||
|
||||
void EmitServiceImplMethodImpls(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitServiceImplMethodImpl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitKernelServiceImplGetMethod(StringBuilder &sb) const;
|
||||
|
||||
void EmitServiceImplGetVersionMethod(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitServiceImplGetMethod(StringBuilder &sb) const;
|
||||
|
||||
void EmitKernelServiceImplReleaseMethod(StringBuilder &sb) const;
|
||||
|
||||
void EmitServiceImplReleaseMethod(StringBuilder &sb) const;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_HDI_C_SERVICE_IMPL_CODE_EMITTER_H
|
811
idl_tool_2/codegen/HDI/c/c_service_stub_code_emitter.cpp
Normal file
811
idl_tool_2/codegen/HDI/c/c_service_stub_code_emitter.cpp
Normal file
@ -0,0 +1,811 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "c_service_stub_code_emitter.h"
|
||||
|
||||
#include "util/file.h"
|
||||
#include "util/logger.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
bool CServiceStubCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
|
||||
{
|
||||
if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
|
||||
directory_ = GetFileParentPath(targetDirectory);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!File::CreateParentDir(directory_)) {
|
||||
Logger::E("CServiceStubCodeEmitter", "Create '%s' failed!", directory_.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitCode()
|
||||
{
|
||||
switch (mode_) {
|
||||
case GenMode::IPC:
|
||||
case GenMode::KERNEL: {
|
||||
EmitServiceStubHeaderFile();
|
||||
EmitServiceStubSourceFile();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitServiceStubHeaderFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(stubName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitHeadMacro(sb, stubFullName_);
|
||||
sb.Append("\n");
|
||||
EmitStubHeaderInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitHeadExternC(sb);
|
||||
sb.Append("\n");
|
||||
EmitCbServiceStubDef(sb);
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
sb.Append("\n");
|
||||
EmitCbServiceStubMethodsDcl(sb);
|
||||
}
|
||||
sb.Append("\n");
|
||||
EmitTailExternC(sb);
|
||||
sb.Append("\n");
|
||||
EmitTailMacro(sb, stubFullName_);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitStubHeaderInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
|
||||
headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_sbuf");
|
||||
|
||||
if (mode_ != GenMode::KERNEL) {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_remote_service");
|
||||
}
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitCbServiceStubDef(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("struct %sStub {\n", baseName_.c_str());
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
sb.Append(TAB).AppendFormat("struct %s interface;\n", interfaceName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("int32_t (*OnRemoteRequest)(struct %s *serviceImpl, ", interfaceName_.c_str());
|
||||
sb.Append("int code, struct HdfSBuf *data, struct HdfSBuf *reply);\n");
|
||||
} else {
|
||||
sb.Append(TAB).Append("struct HdfRemoteService *remote;\n");
|
||||
sb.Append(TAB).AppendFormat("struct %s *interface;\n", interfaceName_.c_str());
|
||||
sb.Append(TAB).Append("struct HdfRemoteDispatcher dispatcher;\n");
|
||||
}
|
||||
sb.Append("};\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitCbServiceStubMethodsDcl(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("bool %sStubConstruct(struct %sStub *stub);\n", baseName_.c_str(), baseName_.c_str());
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitServiceStubSourceFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.c", directory_.c_str(), FileName(stubName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitStubSourceInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitLogTagMacro(sb, FileName(stubName_));
|
||||
if (mode_ != GenMode::KERNEL && !interface_->IsSerializable()) {
|
||||
sb.Append("\n");
|
||||
EmitExternalMethodImpl(sb);
|
||||
}
|
||||
sb.Append("\n");
|
||||
EmitUtilMethods(sb, true);
|
||||
sb.Append("\n");
|
||||
EmitUtilMethods(sb, false);
|
||||
EmitServiceStubMethodImpls(sb, "");
|
||||
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
sb.Append("\n");
|
||||
EmitKernelStubOnRequestMethodImpl(sb, "");
|
||||
sb.Append("\n");
|
||||
EmitKernelStubConstruct(sb);
|
||||
} else {
|
||||
sb.Append("\n");
|
||||
EmitStubOnRequestMethodImpl(sb, "");
|
||||
if (!interface_->IsSerializable()) {
|
||||
sb.Append("\n");
|
||||
EmitStubRemoteDispatcher(sb);
|
||||
}
|
||||
|
||||
sb.Append("\n");
|
||||
EmitStubNewInstance(sb);
|
||||
sb.Append("\n");
|
||||
EmitStubReleaseMethod(sb);
|
||||
sb.Append("\n");
|
||||
EmitStubConstructor(sb);
|
||||
sb.Append("\n");
|
||||
EmitStubRegAndUnreg(sb);
|
||||
}
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitStubSourceInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
|
||||
headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(stubName_));
|
||||
GetSourceOtherLibInclusions(headerFiles);
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
|
||||
{
|
||||
if (mode_ != GenMode::KERNEL) {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_dlist");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "stub_collector");
|
||||
|
||||
if (!interface_->IsSerializable()) {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
|
||||
}
|
||||
} else {
|
||||
const AST::TypeStringMap &types = ast_->GetTypes();
|
||||
for (const auto &pair : types) {
|
||||
AutoPtr<ASTType> type = pair.second;
|
||||
if (type->GetTypeKind() == TypeKind::TYPE_STRING || type->GetTypeKind() == TypeKind::TYPE_UNION) {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "osal_mem");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitExternalMethodImpl(StringBuilder &sb)
|
||||
{
|
||||
EmitGetMethodImpl(sb);
|
||||
sb.Append("\n");
|
||||
EmitGetInstanceMehtodImpl(sb);
|
||||
sb.Append("\n");
|
||||
EmitReleaseMethodImpl(sb);
|
||||
sb.Append("\n");
|
||||
EmitReleaseInstanceMethodImpl(sb);
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitGetMethodImpl(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("struct %s *%sGet(bool isStub)\n", interfaceName_.c_str(), interfaceName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).AppendFormat(
|
||||
"return %sGetInstance(\"%s\", isStub);\n", interfaceName_.c_str(), FileName(implName_).c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitGetInstanceMehtodImpl(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("struct %s *%sGetInstance(const char *serviceName, bool isStub)\n", interfaceName_.c_str(),
|
||||
interfaceName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("if (!isStub) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return NULL;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
sb.Append(TAB).AppendFormat("const char *instName = serviceName;\n");
|
||||
sb.Append(TAB).AppendFormat("if (strcmp(serviceName, \"%s\") == 0) {\n", FileName(implName_).c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("instName = \"service\";\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
sb.Append(TAB).AppendFormat("return (struct %s *)LoadHdiImpl(%s, instName);\n",
|
||||
interfaceName_.c_str(), EmitDescMacroName().c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitReleaseMethodImpl(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat(
|
||||
"void %sRelease(struct %s *instance, bool isStub)\n", interfaceName_.c_str(), interfaceName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).AppendFormat(
|
||||
"%sReleaseInstance(\"%s\", instance, isStub);\n", interfaceName_.c_str(), FileName(implName_).c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitReleaseInstanceMethodImpl(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("void %sReleaseInstance(const char *serviceName, struct %s *instance, bool isStub)\n",
|
||||
interfaceName_.c_str(), interfaceName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("if (serviceName == NULL || !isStub || instance == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
sb.Append(TAB).Append("const char *instName = serviceName;\n");
|
||||
sb.Append(TAB).AppendFormat("if (strcmp(serviceName, \"%s\") == 0) {\n", FileName(implName_).c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("instName = \"service\";\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
sb.Append(TAB).AppendFormat("UnloadHdiImpl(%s, instName, instance);\n", EmitDescMacroName().c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitServiceStubMethodImpls(StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
EmitServiceStubMethodImpl(method, sb, prefix);
|
||||
sb.Append("\n");
|
||||
}
|
||||
|
||||
EmitStubGetVerMethodImpl(interface_->GetVersionMethod(), sb, prefix);
|
||||
if (mode_ != GenMode::KERNEL) {
|
||||
sb.Append("\n");
|
||||
EmitStubAsObjectMethodImpl(sb, prefix);
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitServiceStubMethodImpl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"static int32_t SerStub%s(struct %s *serviceImpl, struct HdfSBuf *%s, struct HdfSBuf *%s)\n",
|
||||
method->GetName().c_str(), interfaceName_.c_str(), HdiTypeEmitter::dataParcelName_.c_str(),
|
||||
HdiTypeEmitter::replyParcelName_.c_str());
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("int32_t %s = HDF_FAILURE;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
bool readFlag = NeedFlag(method);
|
||||
if (readFlag) {
|
||||
sb.Append(prefix + TAB).AppendFormat("bool %s = false;\n", flagOfSetMemName_.c_str());
|
||||
}
|
||||
|
||||
// Local variable definitions must precede all execution statements.
|
||||
EmitMethodNeedLoopVar(method, true, true, sb, prefix + TAB);
|
||||
|
||||
if (method->GetParameterNumber() > 0) {
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
EmitStubLocalVariable(param, sb, prefix + TAB);
|
||||
}
|
||||
|
||||
sb.Append("\n");
|
||||
EmitReadFlagVariable(readFlag, sb, prefix + TAB);
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
if (param->GetAttribute() == ASTParamAttr::PARAM_IN) {
|
||||
EmitReadStubMethodParameter(param, finishedLabel_, sb, prefix + TAB);
|
||||
sb.Append("\n");
|
||||
} else {
|
||||
EmitOutVarMemInitialize(param, finishedLabel_, sb, prefix + TAB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EmitStubCallMethod(method, finishedLabel_, sb, prefix + TAB);
|
||||
sb.Append("\n");
|
||||
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
if (param->GetAttribute() == ASTParamAttr::PARAM_OUT) {
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
|
||||
typeEmitter->EmitCWriteVar(TypeMode::PARAM_OUT, param->GetName(), finishedLabel_, sb, prefix + TAB);
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
EmitErrorHandle(method, sb, prefix);
|
||||
sb.Append(prefix + TAB).AppendFormat("return %s;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitErrorHandle(const AutoPtr<ASTMethod> &method,
|
||||
StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("%s:\n", finishedLabel_);
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
|
||||
typeEmitter->EmitMemoryRecycle(param->GetName(), true, sb, prefix + TAB);
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitReadFlagVariable(bool readFlag, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
if (!readFlag) {
|
||||
return;
|
||||
}
|
||||
|
||||
sb.Append(prefix).AppendFormat("if (!HdfSbufReadUint8(%s, (uint8_t *)&%s)) {\n",
|
||||
HdiTypeEmitter::dataParcelName_.c_str(), flagOfSetMemName_.c_str());
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: read flag of memory setting failed!\", __func__);\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", finishedLabel_);
|
||||
sb.Append(prefix).Append("}\n\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitStubLocalVariable(
|
||||
const AutoPtr<ASTParameter> ¶m, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
AutoPtr<ASTType> type = param->GetType();
|
||||
EmitParamLocalVar(param, sb, prefix);
|
||||
if (type->GetTypeKind() == TypeKind::TYPE_ARRAY || type->GetTypeKind() == TypeKind::TYPE_LIST ||
|
||||
(type->GetTypeKind() == TypeKind::TYPE_STRING && (param->GetAttribute() == ASTParamAttr::PARAM_OUT))) {
|
||||
sb.Append(prefix).AppendFormat("uint32_t %sLen = 0;\n", param->GetName().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitParamLocalVar(const AutoPtr<ASTParameter> ¶m, StringBuilder &sb,
|
||||
const std::string &prefix) const
|
||||
{
|
||||
AutoPtr<ASTType> type = param->GetType();
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
|
||||
sb.Append(prefix).AppendFormat("%s %s", typeEmitter->EmitCType(TypeMode::LOCAL_VAR).c_str(),
|
||||
param->GetName().c_str());
|
||||
switch (type->GetTypeKind()) {
|
||||
case TypeKind::TYPE_BOOLEAN:
|
||||
sb.Append(" = false");
|
||||
break;
|
||||
case TypeKind::TYPE_BYTE:
|
||||
case TypeKind::TYPE_SHORT:
|
||||
case TypeKind::TYPE_INT:
|
||||
case TypeKind::TYPE_LONG:
|
||||
case TypeKind::TYPE_UCHAR:
|
||||
case TypeKind::TYPE_USHORT:
|
||||
case TypeKind::TYPE_UINT:
|
||||
case TypeKind::TYPE_ULONG:
|
||||
case TypeKind::TYPE_FLOAT:
|
||||
case TypeKind::TYPE_DOUBLE:
|
||||
sb.Append(" = 0");
|
||||
break;
|
||||
case TypeKind::TYPE_STRING:
|
||||
case TypeKind::TYPE_ARRAY:
|
||||
case TypeKind::TYPE_LIST:
|
||||
case TypeKind::TYPE_STRUCT:
|
||||
case TypeKind::TYPE_UNION:
|
||||
case TypeKind::TYPE_INTERFACE:
|
||||
case TypeKind::TYPE_NATIVE_BUFFER:
|
||||
sb.Append(" = NULL");
|
||||
break;
|
||||
case TypeKind::TYPE_FILEDESCRIPTOR:
|
||||
sb.Append(" = -1");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sb.Append(";\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitReadStubMethodParameter(const AutoPtr<ASTParameter> ¶m,
|
||||
const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
AutoPtr<ASTType> type = param->GetType();
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
|
||||
|
||||
if (type->GetTypeKind() == TypeKind::TYPE_STRING) {
|
||||
EmitReadCStringStubMethodParameter(param, gotoLabel, sb, prefix, typeEmitter);
|
||||
} else if (type->GetTypeKind() == TypeKind::TYPE_STRUCT) {
|
||||
sb.Append(prefix).AppendFormat("%s = (%s*)OsalMemCalloc(sizeof(%s));\n", param->GetName().c_str(),
|
||||
typeEmitter->EmitCType().c_str(), typeEmitter->EmitCType().c_str());
|
||||
sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", param->GetName().c_str());
|
||||
sb.Append(prefix + TAB)
|
||||
.AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s failed\", __func__);\n", param->GetName().c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", finishedLabel_);
|
||||
sb.Append(prefix).Append("}\n");
|
||||
typeEmitter->EmitCStubReadVar(param->GetName(), gotoLabel, sb, prefix);
|
||||
} else if (type->GetTypeKind() == TypeKind::TYPE_UNION) {
|
||||
std::string cpName = StringHelper::Format("%sCp", param->GetName().c_str());
|
||||
typeEmitter->EmitCStubReadVar(cpName, gotoLabel, sb, prefix);
|
||||
sb.Append(prefix).AppendFormat("%s = (%s*)OsalMemCalloc(sizeof(%s));\n", param->GetName().c_str(),
|
||||
typeEmitter->EmitCType().c_str(), typeEmitter->EmitCType().c_str());
|
||||
sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", param->GetName().c_str());
|
||||
sb.Append(prefix + TAB)
|
||||
.AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s failed\", __func__);\n", param->GetName().c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", finishedLabel_);
|
||||
sb.Append(prefix).Append("}\n");
|
||||
sb.Append(prefix).AppendFormat("if (memcpy_s(%s, sizeof(%s), %s, sizeof(%s)) != EOK) {\n",
|
||||
param->GetName().c_str(), typeEmitter->EmitCType().c_str(), cpName.c_str(),
|
||||
typeEmitter->EmitCType().c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to memcpy %s\", __func__);\n",
|
||||
param->GetName().c_str());
|
||||
sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
} else if (type->GetTypeKind() == TypeKind::TYPE_ARRAY || type->GetTypeKind() == TypeKind::TYPE_LIST ||
|
||||
type->GetTypeKind() == TypeKind::TYPE_FILEDESCRIPTOR ||
|
||||
type->GetTypeKind() == TypeKind::TYPE_NATIVE_BUFFER || type->GetTypeKind() == TypeKind::TYPE_ENUM ||
|
||||
type->GetTypeKind() == TypeKind::TYPE_INTERFACE) {
|
||||
typeEmitter->EmitCStubReadVar(param->GetName(), gotoLabel, sb, prefix);
|
||||
} else {
|
||||
std::string name = StringHelper::Format("&%s", param->GetName().c_str());
|
||||
typeEmitter->EmitCStubReadVar(name, gotoLabel, sb, prefix);
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitReadCStringStubMethodParameter(const AutoPtr<ASTParameter> ¶m,
|
||||
const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix,
|
||||
AutoPtr<HdiTypeEmitter> &typeEmitter) const
|
||||
{
|
||||
std::string cloneName = StringHelper::Format("%sCp", param->GetName().c_str());
|
||||
typeEmitter->EmitCStubReadVar(cloneName, gotoLabel, sb, prefix);
|
||||
if (mode_ == GenMode::KERNEL) {
|
||||
sb.Append("\n");
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"%s = (char*)OsalMemCalloc(strlen(%s) + 1);\n", param->GetName().c_str(), cloneName.c_str());
|
||||
sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", param->GetName().c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB)
|
||||
.AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s failed\", __func__);\n", param->GetName().c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
|
||||
sb.Append(prefix).Append("}\n\n");
|
||||
sb.Append(prefix).AppendFormat("if (strcpy_s(%s, (strlen(%s) + 1), %s) != HDF_SUCCESS) {\n",
|
||||
param->GetName().c_str(), cloneName.c_str(), cloneName.c_str());
|
||||
sb.Append(prefix + TAB)
|
||||
.AppendFormat("HDF_LOGE(\"%%{public}s: read %s failed!\", __func__);\n", param->GetName().c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_PARAM;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
|
||||
sb.Append(prefix).Append("}\n");
|
||||
} else {
|
||||
sb.Append(prefix).AppendFormat("%s = strdup(%s);\n", param->GetName().c_str(), cloneName.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitOutVarMemInitialize(const AutoPtr<ASTParameter> ¶m,
|
||||
const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
AutoPtr<ASTType> type = param->GetType();
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
|
||||
if (type->IsStructType() || type->IsUnionType()) {
|
||||
sb.Append(prefix).AppendFormat("%s = (%s*)OsalMemCalloc(sizeof(%s));\n", param->GetName().c_str(),
|
||||
typeEmitter->EmitCType().c_str(), typeEmitter->EmitCType().c_str());
|
||||
sb.Append(prefix).AppendFormat("if (%s == NULL) {\n", param->GetName().c_str());
|
||||
sb.Append(prefix + TAB)
|
||||
.AppendFormat("HDF_LOGE(\"%%{public}s: malloc %s failed\", __func__);\n", param->GetName().c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_MALLOC_FAIL;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
|
||||
sb.Append(prefix).Append("}\n\n");
|
||||
} else if (type->IsStringType() || type->IsArrayType() || type->IsListType()) {
|
||||
typeEmitter->EmitCStubReadOutVar(flagOfSetMemName_, param->GetName(), gotoLabel, sb, prefix);
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitStubCallMethod(
|
||||
const AutoPtr<ASTMethod> &method, const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).Append("if (serviceImpl == NULL) {\n");
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s: invalid serviceImpl object\", __func__);\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_INVALID_OBJECT;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
|
||||
sb.Append(prefix).Append("}\n\n");
|
||||
|
||||
sb.Append(prefix).AppendFormat("if (serviceImpl->%s == NULL) {\n", method->GetName().c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: invalid interface function %s \", __func__);\n",
|
||||
method->GetName().c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("%s = HDF_ERR_NOT_SUPPORT;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
|
||||
sb.Append(prefix).Append("}\n\n");
|
||||
|
||||
if (method->GetParameterNumber() == 0) {
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"%s = serviceImpl->%s(serviceImpl);\n", HdiTypeEmitter::errorCodeName_.c_str(), method->GetName().c_str());
|
||||
} else {
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"%s = serviceImpl->%s(serviceImpl, ", HdiTypeEmitter::errorCodeName_.c_str(), method->GetName().c_str());
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
EmitCallParameter(sb, param->GetType(), param->GetAttribute(), param->GetName());
|
||||
if (i + 1 < method->GetParameterNumber()) {
|
||||
sb.Append(", ");
|
||||
}
|
||||
}
|
||||
sb.AppendFormat(");\n", method->GetName().c_str());
|
||||
}
|
||||
|
||||
sb.Append(prefix).AppendFormat("if (%s != HDF_SUCCESS) {\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB)
|
||||
.AppendFormat("HDF_LOGE(\"%%{public}s failed, error code is %%{public}d\", __func__, %s);\n",
|
||||
HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("goto %s;\n", gotoLabel.c_str());
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitCallParameter(
|
||||
StringBuilder &sb, const AutoPtr<ASTType> &type, ASTParamAttr::ParamAttr attribute, const std::string &name) const
|
||||
{
|
||||
if (attribute == ASTParamAttr::PARAM_OUT) {
|
||||
if (type->GetTypeKind() == TypeKind::TYPE_STRING || type->GetTypeKind() == TypeKind::TYPE_ARRAY ||
|
||||
type->GetTypeKind() == TypeKind::TYPE_LIST || type->GetTypeKind() == TypeKind::TYPE_STRUCT ||
|
||||
type->GetTypeKind() == TypeKind::TYPE_UNION) {
|
||||
sb.AppendFormat("%s", name.c_str());
|
||||
} else {
|
||||
sb.AppendFormat("&%s", name.c_str());
|
||||
}
|
||||
|
||||
if (type->GetTypeKind() == TypeKind::TYPE_STRING) {
|
||||
sb.AppendFormat(", %sLen", name.c_str());
|
||||
} else if (type->GetTypeKind() == TypeKind::TYPE_ARRAY || type->GetTypeKind() == TypeKind::TYPE_LIST) {
|
||||
sb.AppendFormat(", &%sLen", name.c_str());
|
||||
}
|
||||
}
|
||||
if (attribute == ASTParamAttr::PARAM_IN) {
|
||||
sb.AppendFormat("%s", name.c_str());
|
||||
if (type->GetTypeKind() == TypeKind::TYPE_ARRAY || type->GetTypeKind() == TypeKind::TYPE_LIST) {
|
||||
sb.AppendFormat(", %sLen", name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitStubGetVerMethodImpl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"static int32_t SerStub%s(struct %s *serviceImpl, struct HdfSBuf *%s, struct HdfSBuf *%s)\n",
|
||||
method->GetName().c_str(), interfaceName_.c_str(), HdiTypeEmitter::dataParcelName_.c_str(),
|
||||
HdiTypeEmitter::replyParcelName_.c_str());
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("int32_t %s = HDF_SUCCESS;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(new ASTUintType());
|
||||
typeEmitter->EmitCWriteVar(TypeMode::PARAM_OUT, majorVerName_, finishedLabel_, sb, prefix + TAB);
|
||||
sb.Append("\n");
|
||||
typeEmitter->EmitCWriteVar(TypeMode::PARAM_OUT, minorVerName_, finishedLabel_, sb, prefix + TAB);
|
||||
sb.Append("\n");
|
||||
|
||||
sb.Append(finishedLabel_).Append(":\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("return %s;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitStubAsObjectMethodImpl(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
std::string objName = "self";
|
||||
sb.Append(prefix).AppendFormat("static struct HdfRemoteService *%sStubAsObject(struct %s *%s)\n", baseName_.c_str(),
|
||||
interfaceName_.c_str(), objName.c_str());
|
||||
sb.Append(prefix).Append("{\n");
|
||||
|
||||
if (interface_->IsSerializable()) {
|
||||
sb.Append(prefix + TAB).AppendFormat("if (%s == NULL) {\n", objName.c_str());
|
||||
sb.Append(prefix + TAB + TAB).Append("return NULL;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n");
|
||||
sb.Append(prefix + TAB).AppendFormat(
|
||||
"struct %sStub *stub = CONTAINER_OF(%s, struct %sStub, interface);\n", baseName_.c_str(),
|
||||
objName.c_str(), baseName_.c_str());
|
||||
sb.Append(prefix + TAB).Append("return stub->remote;\n");
|
||||
} else {
|
||||
sb.Append(prefix + TAB).Append("return NULL;\n");
|
||||
}
|
||||
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitKernelStubOnRequestMethodImpl(StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
std::string implName = "serviceImpl";
|
||||
std::string codeName = "code";
|
||||
std::string funcName = StringHelper::Format("%sOnRemoteRequest", baseName_.c_str());
|
||||
sb.Append(prefix).AppendFormat("static int32_t %s(struct %s *%s, ", funcName.c_str(), interfaceName_.c_str(),
|
||||
implName.c_str());
|
||||
sb.AppendFormat("int %s, struct HdfSBuf *data, struct HdfSBuf *reply)\n", codeName.c_str());
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("switch (%s) {\n", codeName.c_str());
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(method).c_str());
|
||||
sb.Append(prefix + TAB + TAB + TAB)
|
||||
.AppendFormat("return SerStub%s(%s, data, reply);\n", method->GetName().c_str(), implName.c_str());
|
||||
}
|
||||
|
||||
AutoPtr<ASTMethod> getVerMethod = interface_->GetVersionMethod();
|
||||
sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(getVerMethod).c_str());
|
||||
sb.Append(prefix + TAB + TAB + TAB)
|
||||
.AppendFormat("return SerStub%s(%s, data, reply);\n", getVerMethod->GetName().c_str(), implName.c_str());
|
||||
|
||||
sb.Append(prefix + TAB + TAB).Append("default: {\n");
|
||||
sb.Append(prefix + TAB + TAB + TAB)
|
||||
.AppendFormat("HDF_LOGE(\"%%{public}s: not support cmd %%{public}d\", __func__, %s);\n", codeName.c_str());
|
||||
sb.Append(prefix + TAB + TAB + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("}\n");
|
||||
sb.Append(prefix + TAB).Append("}\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitKernelStubConstruct(StringBuilder &sb) const
|
||||
{
|
||||
std::string stubTypeName = StringHelper::Format("%sStub", baseName_.c_str());
|
||||
std::string objName = "stub";
|
||||
std::string funcName = StringHelper::Format("%sOnRemoteRequest", baseName_.c_str());
|
||||
|
||||
sb.AppendFormat(
|
||||
"bool %sConstruct(struct %s *%s)\n", stubTypeName.c_str(), stubTypeName.c_str(), objName.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", objName.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: stub is null!\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return false;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
sb.Append(TAB).AppendFormat("%s->OnRemoteRequest = %s;\n", objName.c_str(), funcName.c_str());
|
||||
sb.Append(TAB).Append("return true;\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitStubOnRequestMethodImpl(StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
std::string remoteName = "remote";
|
||||
std::string codeName = "code";
|
||||
std::string funcName = StringHelper::Format("%sOnRemoteRequest", baseName_.c_str());
|
||||
sb.Append(prefix).AppendFormat("static int32_t %s(struct HdfRemoteService *%s, ", funcName.c_str(),
|
||||
remoteName.c_str());
|
||||
sb.AppendFormat("int %s, struct HdfSBuf *data, struct HdfSBuf *reply)\n", codeName.c_str());
|
||||
sb.Append(prefix).Append("{\n");
|
||||
|
||||
sb.Append(prefix + TAB).AppendFormat("struct %s *stub = (struct %s*)%s;\n", stubName_.c_str(),
|
||||
stubName_.c_str(), remoteName.c_str());
|
||||
sb.Append(prefix + TAB).Append("if (stub == NULL || stub->remote == NULL || stub->interface == NULL) {\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid stub object\", __func__);\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n");
|
||||
|
||||
sb.Append(prefix + TAB).AppendFormat("if (!HdfRemoteServiceCheckInterfaceToken(stub->%s, data)) {\n",
|
||||
remoteName.c_str());
|
||||
sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: interface token check failed\", __func__);\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n\n");
|
||||
|
||||
sb.Append(prefix + TAB).AppendFormat("switch (%s) {\n", codeName.c_str());
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(method).c_str());
|
||||
sb.Append(prefix + TAB + TAB + TAB)
|
||||
.AppendFormat("return SerStub%s(stub->interface, data, reply);\n", method->GetName().c_str());
|
||||
}
|
||||
|
||||
AutoPtr<ASTMethod> getVerMethod = interface_->GetVersionMethod();
|
||||
sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(getVerMethod).c_str());
|
||||
sb.Append(prefix + TAB + TAB + TAB)
|
||||
.AppendFormat("return SerStub%s(stub->interface, data, reply);\n", getVerMethod->GetName().c_str());
|
||||
|
||||
sb.Append(prefix + TAB + TAB).Append("default: {\n");
|
||||
sb.Append(prefix + TAB + TAB + TAB)
|
||||
.AppendFormat("HDF_LOGE(\"%%{public}s: not support cmd %%{public}d\", __func__, %s);\n", codeName.c_str());
|
||||
sb.Append(prefix + TAB + TAB + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("}\n");
|
||||
sb.Append(prefix + TAB).Append("}\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitStubRemoteDispatcher(StringBuilder &sb) const
|
||||
{
|
||||
std::string dispatcherName = StringHelper::Format("g_%sDispatcher", StringHelper::StrToLower(baseName_).c_str());
|
||||
sb.AppendFormat("static struct HdfRemoteDispatcher %s = {\n", dispatcherName.c_str());
|
||||
sb.Append(TAB).AppendFormat(".Dispatch = %sOnRemoteRequest,\n", baseName_.c_str());
|
||||
sb.Append(TAB).Append(".DispatchAsync = NULL,\n");
|
||||
sb.Append("};\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitStubNewInstance(StringBuilder &sb) const
|
||||
{
|
||||
std::string dispatcherName = StringHelper::Format("g_%sDispatcher", StringHelper::StrToLower(baseName_).c_str());
|
||||
sb.AppendFormat("static struct HdfRemoteService **%sNewInstance(void *impl)\n", stubName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("if (impl == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: impl is null\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return NULL;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
|
||||
sb.Append(TAB).AppendFormat("struct %s *serviceImpl = (struct %s *)impl;\n", interfaceName_.c_str(),
|
||||
interfaceName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("struct %s *stub = OsalMemCalloc(sizeof(struct %s));\n", stubName_.c_str(),
|
||||
stubName_.c_str());
|
||||
sb.Append(TAB).Append("if (stub == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: failed to malloc stub object\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return NULL;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
|
||||
if (interface_->IsSerializable()) {
|
||||
sb.Append(TAB).Append("stub->remote = HdfRemoteServiceObtain((struct HdfObject *)stub, &stub->dispatcher);\n");
|
||||
} else {
|
||||
sb.Append(TAB).AppendFormat("stub->remote = HdfRemoteServiceObtain((struct HdfObject *)stub, &%s);\n",
|
||||
dispatcherName.c_str());
|
||||
}
|
||||
|
||||
sb.Append(TAB).Append("if (stub->remote == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("OsalMemFree(stub);\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return NULL;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
sb.Append(TAB).AppendFormat("(void)HdfRemoteServiceSetInterfaceDesc(stub->remote, %s);\n",
|
||||
EmitDescMacroName().c_str());
|
||||
sb.Append(TAB).AppendFormat("stub->dispatcher.Dispatch = %sOnRemoteRequest;\n", baseName_.c_str());
|
||||
sb.Append(TAB).Append("stub->interface = serviceImpl;\n");
|
||||
sb.Append(TAB).AppendFormat("stub->interface->AsObject = %sStubAsObject;\n", baseName_.c_str());
|
||||
sb.Append(TAB).Append("return &stub->remote;\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitStubReleaseMethod(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("static void %sRelease(struct HdfRemoteService **remote)\n", stubName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("if (remote == NULL) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
sb.Append(TAB).AppendFormat("struct %s *stub = CONTAINER_OF(remote, struct %s, remote);\n",
|
||||
stubName_.c_str(), stubName_.c_str());
|
||||
sb.Append(TAB).Append("HdfRemoteServiceRecycle(stub->remote);\n");
|
||||
sb.Append(TAB).Append("OsalMemFree(stub);\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitStubConstructor(StringBuilder &sb) const
|
||||
{
|
||||
std::string constructorName = StringHelper::Format("g_%sConstructor", StringHelper::StrToLower(baseName_).c_str());
|
||||
sb.AppendFormat("__attribute__((unused)) static struct StubConstructor %s = {\n", constructorName.c_str());
|
||||
sb.Append(TAB).AppendFormat(".constructor = %sNewInstance,\n", stubName_.c_str());
|
||||
sb.Append(TAB).AppendFormat(".destructor = %sRelease,\n", stubName_.c_str());
|
||||
sb.Append("};\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitStubRegAndUnreg(StringBuilder &sb) const
|
||||
{
|
||||
std::string constructorName = StringHelper::Format("g_%sConstructor", StringHelper::StrToLower(baseName_).c_str());
|
||||
sb.AppendFormat("__attribute__((constructor)) static void %sRegister(void)\n", stubName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).AppendFormat(
|
||||
"HDF_LOGI(\"%%{public}s: register stub constructor of '%%{public}s'\", __func__, %s);\n",
|
||||
EmitDescMacroName().c_str());
|
||||
sb.Append(TAB).AppendFormat("StubConstructorRegister(%s, &%s);\n", EmitDescMacroName().c_str(),
|
||||
constructorName.c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CServiceStubCodeEmitter::EmitUtilMethods(StringBuilder &sb, bool isDecl)
|
||||
{
|
||||
UtilMethodMap methods;
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
|
||||
if (param->GetAttribute() == ASTParamAttr::PARAM_IN) {
|
||||
typeEmitter->EmitCStubReadMethods(methods, "", "", isDecl);
|
||||
} else {
|
||||
typeEmitter->EmitCWriteMethods(methods, "", "", isDecl);
|
||||
}
|
||||
}
|
||||
}
|
||||
EmitUtilMethodMap(sb, methods);
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
114
idl_tool_2/codegen/HDI/c/c_service_stub_code_emitter.h
Normal file
114
idl_tool_2/codegen/HDI/c/c_service_stub_code_emitter.h
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_HDI_C_SERVICE_STUB_CODEE_MITTER_H
|
||||
#define OHOS_IDL_HDI_C_SERVICE_STUB_CODEE_MITTER_H
|
||||
|
||||
#include "hdi_c_code_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
class CServiceStubCodeEmitter : public HDICCodeEmitter {
|
||||
public:
|
||||
CServiceStubCodeEmitter() : HDICCodeEmitter() {}
|
||||
|
||||
~CServiceStubCodeEmitter() override = default;
|
||||
|
||||
private:
|
||||
bool ResolveDirectory(const std::string &targetDirectory) override;
|
||||
|
||||
void EmitCode() override;
|
||||
|
||||
void EmitServiceStubHeaderFile();
|
||||
|
||||
void EmitStubHeaderInclusions(StringBuilder &sb);
|
||||
|
||||
void EmitCbServiceStubDef(StringBuilder &sb) const;
|
||||
|
||||
void EmitCbServiceStubMethodsDcl(StringBuilder &sb) const;
|
||||
|
||||
void EmitServiceStubSourceFile();
|
||||
|
||||
void EmitStubSourceInclusions(StringBuilder &sb);
|
||||
|
||||
void GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const;
|
||||
|
||||
// get or release method for driver interface object
|
||||
void EmitExternalMethodImpl(StringBuilder &sb);
|
||||
|
||||
void EmitGetMethodImpl(StringBuilder &sb) const;
|
||||
|
||||
void EmitGetInstanceMehtodImpl(StringBuilder &sb) const;
|
||||
|
||||
void EmitReleaseMethodImpl(StringBuilder &sb) const;
|
||||
|
||||
void EmitReleaseInstanceMethodImpl(StringBuilder &sb) const;
|
||||
|
||||
void EmitServiceStubMethodImpls(StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitServiceStubMethodImpl(const AutoPtr<ASTMethod> &method, StringBuilder &sb,
|
||||
const std::string &prefix) const;
|
||||
|
||||
void EmitReadFlagVariable(bool readFlag, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitStubLocalVariable(const AutoPtr<ASTParameter> ¶m, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitReadStubMethodParameter(const AutoPtr<ASTParameter> ¶m, const std::string &gotoLabel,
|
||||
StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitReadCStringStubMethodParameter(const AutoPtr<ASTParameter> ¶m, const std::string &gotoLabel,
|
||||
StringBuilder &sb, const std::string &prefix, AutoPtr<HdiTypeEmitter> &typeEmitter) const;
|
||||
|
||||
void EmitOutVarMemInitialize(const AutoPtr<ASTParameter> ¶m, const std::string &gotoLabel, StringBuilder &sb,
|
||||
const std::string &prefix) const;
|
||||
|
||||
void EmitStubCallMethod(const AutoPtr<ASTMethod> &method,
|
||||
const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitCallParameter(StringBuilder &sb, const AutoPtr<ASTType> &type, ASTParamAttr::ParamAttr attribute,
|
||||
const std::string &name) const;
|
||||
|
||||
void EmitStubGetVerMethodImpl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitStubAsObjectMethodImpl(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitKernelStubOnRequestMethodImpl(StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitKernelStubConstruct(StringBuilder &sb) const;
|
||||
|
||||
void EmitStubOnRequestMethodImpl(StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitStubRemoteDispatcher(StringBuilder &sb) const;
|
||||
|
||||
void EmitStubNewInstance(StringBuilder &sb) const;
|
||||
|
||||
void EmitStubReleaseMethod(StringBuilder &sb) const;
|
||||
|
||||
void EmitStubConstructor(StringBuilder &sb) const;
|
||||
|
||||
void EmitStubRegAndUnreg(StringBuilder &sb) const;
|
||||
|
||||
void EmitUtilMethods(StringBuilder &sb, bool isDecl) override;
|
||||
|
||||
void EmitParamLocalVar(const AutoPtr<ASTParameter> ¶m, StringBuilder &sb,
|
||||
const std::string &prefix) const;
|
||||
|
||||
void EmitErrorHandle(const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_HDI_C_SERVICE_STUB_CODEE_MITTER_H
|
208
idl_tool_2/codegen/HDI/c/hdi_c_code_emitter.cpp
Normal file
208
idl_tool_2/codegen/HDI/c/hdi_c_code_emitter.cpp
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "hdi_c_code_emitter.h"
|
||||
#include "util/options.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
void HDICCodeEmitter::GetStdlibInclusions(HeaderFile::HeaderFileSet &headerFiles)
|
||||
{
|
||||
const AST::TypeStringMap &types = ast_->GetTypes();
|
||||
for (const auto &pair : types) {
|
||||
AutoPtr<ASTType> type = pair.second;
|
||||
if (type->IsNativeBufferType()) {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "base/buffer_util");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HDICCodeEmitter::GetImportInclusions(HeaderFile::HeaderFileSet &headerFiles)
|
||||
{
|
||||
for (const auto &importPair : ast_->GetImports()) {
|
||||
AutoPtr<AST> importAst = importPair.second;
|
||||
std::string fileName = PackageToFilePath(importAst->GetFullName());
|
||||
headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, fileName);
|
||||
}
|
||||
}
|
||||
|
||||
void HDICCodeEmitter::EmitInterfaceMethodParameter(
|
||||
const AutoPtr<ASTParameter> ¶meter, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
std::string name = parameter->GetName();
|
||||
AutoPtr<ASTType> type = parameter->GetType();
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
|
||||
ASTParamAttr::ParamAttr attrAttr = parameter->GetAttribute();
|
||||
std::string typeName = (attrAttr == ASTParamAttr::PARAM_IN) ?
|
||||
typeEmitter->EmitCType(TypeMode::PARAM_IN) : typeEmitter->EmitCType(TypeMode::PARAM_OUT);
|
||||
|
||||
switch (type->GetTypeKind()) {
|
||||
case TypeKind::TYPE_BOOLEAN:
|
||||
case TypeKind::TYPE_BYTE:
|
||||
case TypeKind::TYPE_SHORT:
|
||||
case TypeKind::TYPE_INT:
|
||||
case TypeKind::TYPE_LONG:
|
||||
case TypeKind::TYPE_UCHAR:
|
||||
case TypeKind::TYPE_USHORT:
|
||||
case TypeKind::TYPE_UINT:
|
||||
case TypeKind::TYPE_ULONG:
|
||||
case TypeKind::TYPE_FLOAT:
|
||||
case TypeKind::TYPE_DOUBLE:
|
||||
case TypeKind::TYPE_ENUM:
|
||||
case TypeKind::TYPE_FILEDESCRIPTOR:
|
||||
case TypeKind::TYPE_INTERFACE:
|
||||
case TypeKind::TYPE_STRING:
|
||||
case TypeKind::TYPE_STRUCT:
|
||||
case TypeKind::TYPE_UNION:
|
||||
case TypeKind::TYPE_NATIVE_BUFFER:
|
||||
case TypeKind::TYPE_POINTER:
|
||||
case TypeKind::TYPE_ARRAY:
|
||||
case TypeKind::TYPE_LIST:
|
||||
sb.Append(prefix).AppendFormat("%s %s", typeName.c_str(), name.c_str());
|
||||
if ((type->GetTypeKind() == TypeKind::TYPE_STRING) && (attrAttr == ASTParamAttr::PARAM_OUT)) {
|
||||
sb.AppendFormat(", uint32_t %sLen", name.c_str());
|
||||
}
|
||||
if ((type->GetTypeKind() == TypeKind::TYPE_ARRAY) || (type->GetTypeKind() == TypeKind::TYPE_LIST)) {
|
||||
sb.AppendFormat(", uint32_t%s %sLen", (attrAttr == ASTParamAttr::PARAM_OUT) ? "*" : "", name.c_str());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sb.Append(prefix).AppendFormat("unknow type %s", name.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HDICCodeEmitter::EmitMethodNeedLoopVar(
|
||||
const AutoPtr<ASTMethod> &method, bool needRW, bool needFree, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
if (mode_ != GenMode::KERNEL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
if (EmitNeedLoopVar(param->GetType(), needRW, needFree)) {
|
||||
sb.Append(prefix).Append("uint32_t i = 0;\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool HDICCodeEmitter::EmitNeedLoopVar(const AutoPtr<ASTType> &type, bool needRW, bool needFree) const
|
||||
{
|
||||
if (type == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto rwNeedLoopVar = [needRW](const AutoPtr<ASTType> &elementType) -> bool {
|
||||
if (!needRW) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (elementType->IsPod()) {
|
||||
return elementType->IsBooleanType() ? true : false;
|
||||
}
|
||||
|
||||
return elementType->IsStringType() ? false : true;
|
||||
};
|
||||
|
||||
auto freeNeedLoopVar = [needFree](const AutoPtr<ASTType> &elementType) -> bool {
|
||||
if (!needFree) {
|
||||
return false;
|
||||
}
|
||||
return elementType->IsPod() ? false : true;
|
||||
};
|
||||
|
||||
if (type->IsArrayType()) {
|
||||
AutoPtr<ASTArrayType> arrType = dynamic_cast<ASTArrayType *>(type.Get());
|
||||
if (rwNeedLoopVar(arrType->GetElementType()) || freeNeedLoopVar(arrType->GetElementType())) {
|
||||
return true;
|
||||
}
|
||||
} else if (type->IsListType()) {
|
||||
AutoPtr<ASTListType> listType = dynamic_cast<ASTListType *>(type.Get());
|
||||
if (rwNeedLoopVar(listType->GetElementType()) || freeNeedLoopVar(listType->GetElementType())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void HDICCodeEmitter::EmitHeadMacro(StringBuilder &sb, const std::string &fullName) const
|
||||
{
|
||||
std::string macroName = MacroName(fullName);
|
||||
sb.Append("#ifndef ").Append(macroName).Append("\n");
|
||||
sb.Append("#define ").Append(macroName).Append("\n");
|
||||
}
|
||||
|
||||
void HDICCodeEmitter::EmitTailMacro(StringBuilder &sb, const std::string &fullName) const
|
||||
{
|
||||
std::string macroName = MacroName(fullName);
|
||||
sb.Append("#endif // ").Append(macroName);
|
||||
}
|
||||
|
||||
void HDICCodeEmitter::EmitHeadExternC(StringBuilder &sb) const
|
||||
{
|
||||
sb.Append("#ifdef __cplusplus\n");
|
||||
sb.Append("extern \"C\" {\n");
|
||||
sb.Append("#endif /* __cplusplus */\n");
|
||||
}
|
||||
|
||||
void HDICCodeEmitter::EmitTailExternC(StringBuilder &sb) const
|
||||
{
|
||||
sb.Append("#ifdef __cplusplus\n");
|
||||
sb.Append("}\n");
|
||||
sb.Append("#endif /* __cplusplus */\n");
|
||||
}
|
||||
|
||||
std::string HDICCodeEmitter::MacroName(const std::string &name) const
|
||||
{
|
||||
if (name.empty()) {
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string macro = StringHelper::StrToUpper(StringHelper::Replace(name, '.', '_')) + "_H";
|
||||
return macro;
|
||||
}
|
||||
|
||||
std::string HDICCodeEmitter::SpecificationParam(StringBuilder ¶mSb, const std::string &prefix) const
|
||||
{
|
||||
size_t maxLineLen = 120;
|
||||
size_t replaceLen = 2;
|
||||
std::string paramStr = paramSb.ToString();
|
||||
size_t preIndex = 0;
|
||||
size_t curIndex = 0;
|
||||
|
||||
std::string insertStr = StringHelper::Format("\n%s", prefix.c_str());
|
||||
for (; curIndex < paramStr.size(); curIndex++) {
|
||||
if (curIndex == maxLineLen && preIndex > 0) {
|
||||
StringHelper::Replace(paramStr, preIndex, replaceLen, ",");
|
||||
paramStr.insert(preIndex + 1, insertStr);
|
||||
} else {
|
||||
if (paramStr[curIndex] == ',') {
|
||||
preIndex = curIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
return paramStr;
|
||||
}
|
||||
|
||||
std::string HDICCodeEmitter::EmitDescMacroName() const
|
||||
{
|
||||
return StringHelper::Format("%s_INTERFACE_DESC", StringHelper::StrToUpper(interface_->GetName()).c_str());
|
||||
}
|
||||
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
60
idl_tool_2/codegen/HDI/c/hdi_c_code_emitter.h
Normal file
60
idl_tool_2/codegen/HDI/c/hdi_c_code_emitter.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_HDI_C_CODE_EMITTER_H
|
||||
#define OHOS_IDL_HDI_C_CODE_EMITTER_H
|
||||
|
||||
#include "codegen/HDI/hdi_code_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
class HDICCodeEmitter : public HDICodeEmitter {
|
||||
public:
|
||||
~HDICCodeEmitter() override = default;
|
||||
|
||||
protected:
|
||||
void GetStdlibInclusions(HeaderFile::HeaderFileSet &headerFiles);
|
||||
|
||||
void GetImportInclusions(HeaderFile::HeaderFileSet &headerFiles);
|
||||
|
||||
void EmitInterfaceMethodParameter(
|
||||
const AutoPtr<ASTParameter> ¶meter, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitMethodNeedLoopVar(const AutoPtr<ASTMethod> &method,
|
||||
bool needRW, bool needFree, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
bool EmitNeedLoopVar(const AutoPtr<ASTType> &type, bool needRW, bool needFree) const;
|
||||
|
||||
void EmitHeadMacro(StringBuilder &sb, const std::string &fullName) const;
|
||||
|
||||
void EmitTailMacro(StringBuilder &sb, const std::string &fullName) const;
|
||||
|
||||
void EmitHeadExternC(StringBuilder &sb) const;
|
||||
|
||||
void EmitTailExternC(StringBuilder &sb) const;
|
||||
|
||||
std::string MacroName(const std::string &name) const;
|
||||
|
||||
std::string SpecificationParam(StringBuilder ¶mSb, const std::string &prefix) const;
|
||||
|
||||
std::string EmitDescMacroName() const;
|
||||
|
||||
static constexpr const char *errorsLabel_ = "ERRORS";
|
||||
static constexpr const char *finishedLabel_ = "FINISHED";
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_HDI_C_CODE_EMITTER_H
|
872
idl_tool_2/codegen/HDI/cpp/cpp_client_proxy_code_emitter.cpp
Normal file
872
idl_tool_2/codegen/HDI/cpp/cpp_client_proxy_code_emitter.cpp
Normal file
@ -0,0 +1,872 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "cpp_client_proxy_code_emitter.h"
|
||||
#include "util/file.h"
|
||||
#include "util/logger.h"
|
||||
#include "util/string_helper.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
bool CppClientProxyCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
|
||||
{
|
||||
if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
|
||||
directory_ = GetFileParentPath(targetDirectory);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!File::CreateParentDir(directory_)) {
|
||||
Logger::E("CppClientProxyCodeEmitter", "Create '%s' failed!", directory_.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitCode()
|
||||
{
|
||||
switch (mode_) {
|
||||
case GenMode::PASSTHROUGH: {
|
||||
if (!interface_->IsSerializable()) {
|
||||
EmitPassthroughProxySourceFile();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GenMode::IPC: {
|
||||
EmitProxyHeaderFile();
|
||||
EmitProxySourceFile();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyHeaderFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(baseName_ + "Proxy").c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitHeadMacro(sb, proxyFullName_);
|
||||
sb.Append("\n");
|
||||
EmitProxyHeaderInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitBeginNamespace(sb);
|
||||
sb.Append("\n");
|
||||
EmitProxyDecl(sb, "");
|
||||
sb.Append("\n");
|
||||
EmitEndNamespace(sb);
|
||||
sb.Append("\n");
|
||||
EmitTailMacro(sb, proxyFullName_);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyHeaderInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
|
||||
headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
|
||||
if (interface_->GetExtendsInterface() != nullptr) {
|
||||
headerFiles.emplace(
|
||||
HeaderFileType::OWN_HEADER_FILE, EmitHeaderNameByInterface(interface_->GetExtendsInterface(), proxyName_));
|
||||
}
|
||||
GetHeaderOtherLibInclusions(headerFiles);
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
|
||||
{
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iproxy_broker");
|
||||
if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
|
||||
headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "unistd");
|
||||
}
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyDecl(StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
(void)prefix;
|
||||
sb.AppendFormat("class %s : public IProxyBroker<%s> {\n", proxyName_.c_str(),
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
sb.Append("public:\n");
|
||||
if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
|
||||
EmitProxyDevmgrDeathRecipient(sb, TAB);
|
||||
sb.Append("\n");
|
||||
}
|
||||
EmitProxyConstructor(sb, TAB);
|
||||
sb.Append("\n");
|
||||
EmitProxyMethodDecls(sb, TAB);
|
||||
sb.Append("\n");
|
||||
if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
|
||||
EmitProxyPublicMembers(sb, TAB);
|
||||
}
|
||||
sb.Append("private:\n");
|
||||
EmitProxyConstants(sb, TAB);
|
||||
sb.Append("};\n");
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyDevmgrDeathRecipient(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
std::string doubleTab = prefix + TAB;
|
||||
sb.Append(prefix).AppendFormat("class %s : public IRemoteObject::DeathRecipient {\n",
|
||||
devmgrDeathRecipientName_.c_str());
|
||||
sb.Append(prefix).Append("public:\n");
|
||||
sb.Append(doubleTab).AppendFormat("%s(wptr<%s> proxy) : proxy_(proxy) {} \n", devmgrDeathRecipientName_.c_str(),
|
||||
EmitDefinitionByInterface(interface_, proxyName_).c_str());
|
||||
sb.Append(doubleTab).AppendFormat("~%s() override = default;\n", devmgrDeathRecipientName_.c_str());
|
||||
EmitProxyDevmgrDeathCallBack(sb, doubleTab);
|
||||
sb.Append(prefix).Append("private:\n");
|
||||
sb.Append(doubleTab).AppendFormat("wptr<%s> proxy_;\n",
|
||||
EmitDefinitionByInterface(interface_, proxyName_).c_str());
|
||||
sb.Append(prefix).Append("};\n");
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyDevmgrDeathCallBack(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
std::string trebleTab = prefix + TAB;
|
||||
sb.Append(prefix).Append("void OnRemoteDied(const wptr<IRemoteObject> &remote) override\n");
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(trebleTab).Append("int32_t result = HDF_FAILURE;\n");
|
||||
sb.Append(trebleTab).Append("const int sleepInterval = 500000;\n");
|
||||
sb.Append(trebleTab).Append("const int waitTimes = 10;\n");
|
||||
sb.Append(trebleTab).Append("int currentTime = waitTimes;\n");
|
||||
sb.Append(trebleTab).Append("do {\n");
|
||||
sb.Append(trebleTab + TAB).Append("usleep(sleepInterval);\n");
|
||||
sb.Append(trebleTab + TAB).Append("auto proxy = proxy_.promote();\n");
|
||||
sb.Append(trebleTab + TAB).Append("if (proxy != nullptr) {\n");
|
||||
sb.Append(trebleTab + TAB + TAB).AppendFormat("result = %s::Reconnect(proxy);\n",
|
||||
EmitDefinitionByInterface(interface_, proxyName_).c_str());
|
||||
sb.Append(trebleTab + TAB).Append("}\n");
|
||||
sb.Append(trebleTab + TAB).Append("--currentTime;\n");
|
||||
sb.Append(trebleTab).Append("} while (result != HDF_SUCCESS && currentTime >0);\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyConstructor(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("explicit %s(const sptr<IRemoteObject>& remote)", proxyName_.c_str());
|
||||
sb.AppendFormat(
|
||||
" : IProxyBroker<%s>(remote) {\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
|
||||
sb.Append(prefix + TAB).Append("reconnectRemote_ = nullptr;\n");
|
||||
sb.Append(prefix + TAB).Append("isReconnected_ = false;\n");
|
||||
}
|
||||
sb.Append(prefix).AppendFormat("}\n");
|
||||
sb.Append(prefix).AppendFormat("virtual ~%s() = default;\n", proxyName_.c_str());
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyMethodDecls(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
EmitProxyIsProxyMethodImpl(sb, prefix);
|
||||
AutoPtr<ASTInterfaceType> interface = interface_;
|
||||
while (interface != nullptr) {
|
||||
for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
EmitProxyMethodDecl(method, sb, prefix);
|
||||
sb.Append("\n");
|
||||
}
|
||||
interface = interface->GetExtendsInterface();
|
||||
}
|
||||
EmitProxyMethodDecl(interface_->GetVersionMethod(), sb, prefix);
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
sb.Append("\n");
|
||||
EmitProxyStaticMethodDecl(method, sb, prefix);
|
||||
}
|
||||
if (interface_->GetExtendsInterface() == nullptr) {
|
||||
sb.Append("\n");
|
||||
EmitProxyStaticMethodDecl(interface_->GetVersionMethod(), sb, prefix);
|
||||
}
|
||||
if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
|
||||
sb.Append("\n");
|
||||
EmitProxyReconnectMethodDecl(sb, prefix);
|
||||
sb.Append("\n");
|
||||
EmitProxyGetRemoteMethodDecl(sb, prefix);
|
||||
}
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyMethodDecl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
if (method->GetParameterNumber() == 0) {
|
||||
sb.Append(prefix).AppendFormat("int32_t %s() override;\n", method->GetName().c_str());
|
||||
} else {
|
||||
StringBuilder paramStr;
|
||||
paramStr.Append(prefix).AppendFormat("int32_t %s(", method->GetName().c_str());
|
||||
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
EmitInterfaceMethodParameter(param, paramStr, "");
|
||||
if (i + 1 < method->GetParameterNumber()) {
|
||||
paramStr.Append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
paramStr.Append(") override;");
|
||||
|
||||
sb.Append(SpecificationParam(paramStr, prefix + TAB));
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyStaticMethodDecl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
if (method->GetParameterNumber() == 0) {
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"static int32_t %s_(const sptr<IRemoteObject> remote);\n", method->GetName().c_str());
|
||||
} else {
|
||||
StringBuilder paramStr;
|
||||
paramStr.Append(prefix).AppendFormat("static int32_t %s_(", method->GetName().c_str());
|
||||
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
EmitInterfaceMethodParameter(param, paramStr, "");
|
||||
paramStr.Append(", ");
|
||||
}
|
||||
paramStr.Append("const sptr<IRemoteObject> remote");
|
||||
|
||||
paramStr.Append(");");
|
||||
|
||||
sb.Append(SpecificationParam(paramStr, prefix + TAB));
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyReconnectMethodDecl(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
std::string doubleTab = prefix + TAB;
|
||||
sb.Append(prefix).AppendFormat("static int32_t Reconnect(sptr<%s> proxy);\n",
|
||||
EmitDefinitionByInterface(interface_, proxyName_).c_str());
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyGetRemoteMethodDecl(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).Append("sptr<IRemoteObject> GetCurrentRemote() {\n");
|
||||
sb.Append(prefix + TAB).Append("return isReconnected_ ? reconnectRemote_ : Remote();\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyPublicMembers(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).Append("bool isReconnected_;\n");
|
||||
sb.Append(prefix).Append("std::string serviceName_;\n");
|
||||
sb.Append(prefix).AppendFormat("sptr<IRemoteObject> servMgr_;\n", devmgrVersionName_.c_str());
|
||||
sb.Append(prefix).Append("sptr<IRemoteObject> reconnectRemote_;\n");
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyConstants(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"static inline BrokerDelegator<%s> delegator_;\n", EmitDefinitionByInterface(interface_, proxyName_).c_str());
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitPassthroughProxySourceFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(proxyName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitPassthroughProxySourceInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitLogTagMacro(sb, FileName(proxyName_));
|
||||
sb.Append("\n");
|
||||
EmitBeginNamespace(sb);
|
||||
EmitGetMethodImpl(sb, "");
|
||||
sb.Append("\n");
|
||||
EmitPassthroughGetInstanceMethodImpl(sb, "");
|
||||
EmitEndNamespace(sb);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitPassthroughProxySourceInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
|
||||
headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
|
||||
if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
|
||||
headerFiles.emplace(HeaderFileType::CPP_STD_HEADER_FILE, "codecvt");
|
||||
headerFiles.emplace(HeaderFileType::CPP_STD_HEADER_FILE, "locale");
|
||||
} else {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "string_ex");
|
||||
}
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitPassthroughGetInstanceMethodImpl(StringBuilder &sb,
|
||||
const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("%s %s::Get(const std::string &serviceName, bool isStub)\n",
|
||||
GetTypeEmitter(interface_.Get())->EmitCppType().c_str(), interface_->GetName().c_str());
|
||||
sb.Append(prefix).Append("{\n");
|
||||
EmitProxyPassthroughtLoadImpl(sb, prefix + TAB);
|
||||
sb.Append(prefix + TAB).Append("return nullptr;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxySourceFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(proxyName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitProxySourceInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitLogTagMacro(sb, FileName(proxyName_));
|
||||
sb.Append("\n");
|
||||
EmitBeginNamespace(sb);
|
||||
sb.Append("\n");
|
||||
EmitUtilMethods(sb, true);
|
||||
sb.Append("\n");
|
||||
if (interface_->GetExtendsInterface() != nullptr) {
|
||||
EmitProxyCastFromMethodImplTemplate(sb, "");
|
||||
sb.Append("\n");
|
||||
}
|
||||
if (!interface_->IsSerializable()) {
|
||||
EmitGetMethodImpl(sb, "");
|
||||
sb.Append("\n");
|
||||
EmitGetInstanceMethodImpl(sb, "");
|
||||
sb.Append("\n");
|
||||
EmitProxyCppReconnectMethodImpl(sb, "");
|
||||
sb.Append("\n");
|
||||
}
|
||||
EmitProxyCastFromMethodImpls(sb, "");
|
||||
EmitUtilMethods(sb, false);
|
||||
EmitProxyMethodImpls(sb, "");
|
||||
sb.Append("\n");
|
||||
EmitEndNamespace(sb);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxySourceInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(proxyName_));
|
||||
GetSourceOtherLibInclusions(headerFiles);
|
||||
GetSourceOtherFileInclusions(headerFiles);
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
|
||||
{
|
||||
if (!interface_->IsSerializable()) {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iservmgr_hdi");
|
||||
}
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_option");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_parcel");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "string_ex");
|
||||
|
||||
const AST::TypeStringMap &types = ast_->GetTypes();
|
||||
for (const auto &pair : types) {
|
||||
AutoPtr<ASTType> type = pair.second;
|
||||
if (type->GetTypeKind() == TypeKind::TYPE_UNION) {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
|
||||
AutoPtr<ASTType> paramType = param->GetType();
|
||||
if ((param->GetAttribute() == ASTParamAttr::PARAM_IN) &&
|
||||
(paramType->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "object_collector");
|
||||
}
|
||||
|
||||
if ((param->GetAttribute() == ASTParamAttr::PARAM_OUT) &&
|
||||
(paramType->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iproxy_broker");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::GetSourceOtherFileInclusions(HeaderFile::HeaderFileSet &headerFiles) const
|
||||
{
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
|
||||
AutoPtr<ASTType> paramType = param->GetType();
|
||||
if ((param->GetAttribute() == ASTParamAttr::PARAM_OUT) &&
|
||||
(param->GetType()->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
|
||||
AutoPtr<ASTInterfaceType> type = dynamic_cast<ASTInterfaceType *>(paramType.Get());
|
||||
std::string FileName = InterfaceToFilePath(paramType->ToString());
|
||||
headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, FileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitGetMethodImpl(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("%s %s::Get(bool isStub)\n", GetTypeEmitter(interface_.Get())->EmitCppType().c_str(),
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB)
|
||||
.AppendFormat("return %s::Get(\"%s\", isStub);\n", interfaceName_.c_str(), FileName(implName_).c_str());
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitGetInstanceMethodImpl(StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
std::string objName = "proxy";
|
||||
std::string interfaceNamespace = GetNameSpaceByInterface(interface_, interfaceName_);
|
||||
sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(const std::string& serviceName, bool isStub)\n",
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
sb.Append(prefix).Append("{\n");
|
||||
EmitProxyPassthroughtLoadImpl(sb, prefix + TAB);
|
||||
sb.Append(prefix + TAB).AppendFormat("using namespace %s;\n", devmgrVersionName_.c_str());
|
||||
sb.Append(prefix + TAB).Append("auto servMgr = IServiceManager::Get();\n");
|
||||
sb.Append(prefix + TAB).Append("if (servMgr == nullptr) {\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get IServiceManager failed!\", __func__);\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n\n");
|
||||
sb.Append(prefix + TAB).Append("sptr<IRemoteObject> remote = ");
|
||||
sb.Append("servMgr->GetService(serviceName.c_str());\n");
|
||||
sb.Append(prefix + TAB).Append("if (remote == nullptr) {\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get remote object failed!\", __func__);\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("sptr<%s> %s = new %s(remote);\n",
|
||||
EmitDefinitionByInterface(interface_, proxyName_).c_str(), objName.c_str(),
|
||||
(interfaceNamespace +
|
||||
(StringHelper::StartWith(interfaceName_, "I") ? interfaceName_.substr(1) : interfaceName_) +
|
||||
"Proxy").c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("if (%s == nullptr) {\n", objName.c_str());
|
||||
sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:iface_cast failed!\", __func__);\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n\n");
|
||||
EmitGetInstanceMethodInitProxyImpl(sb, prefix);
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitGetInstanceMethodInitProxyImpl(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
std::string objName = "proxy";
|
||||
std::string serMajorName = "serMajorVer";
|
||||
std::string serMinorName = "serMinorVer";
|
||||
sb.Append(prefix + TAB).AppendFormat("%s->servMgr_ = ", objName.c_str());
|
||||
sb.Append("OHOS::HDI::hdi_objcast<IServiceManager>(servMgr);\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("%s->servMgr_->AddDeathRecipient(\n", objName.c_str());
|
||||
sb.Append(prefix + TAB + TAB).AppendFormat("new %s::%s(%s));\n",
|
||||
EmitDefinitionByInterface(interface_, proxyName_).c_str(),
|
||||
devmgrDeathRecipientName_.c_str(), objName.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("%s->isReconnected_ = false;\n", objName.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("%s->serviceName_ = serviceName;\n", objName.c_str());
|
||||
|
||||
sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMajorName.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMinorName.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("int32_t %s = %s->GetVersion(%s, %s);\n",
|
||||
HdiTypeEmitter::errorCodeName_.c_str(), objName.c_str(), serMajorName.c_str(), serMinorName.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("if (%s != HDF_SUCCESS) {\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get version failed!\", __func__);\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n\n");
|
||||
|
||||
sb.Append(prefix + TAB).AppendFormat("if (%s != %d) {\n", serMajorName.c_str(), ast_->GetMajorVer());
|
||||
sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:check version failed! ");
|
||||
sb.Append("version of service:%u.%u");
|
||||
sb.AppendFormat(", version of client:%d.%d\", __func__, ", ast_->GetMajorVer(), ast_->GetMinorVer());
|
||||
sb.AppendFormat("%s, %s);\n", serMajorName.c_str(), serMinorName.c_str());
|
||||
sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("return %s;\n", objName.c_str());
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyCppReconnectMethodImpl(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
std::string doubleTab = prefix + TAB;
|
||||
sb.Append(prefix).AppendFormat("int32_t %s::Reconnect(\n",
|
||||
EmitDefinitionByInterface(interface_, proxyName_).c_str());
|
||||
sb.Append(doubleTab).AppendFormat("sptr<%s> proxy) \n",
|
||||
EmitDefinitionByInterface(interface_, proxyName_).c_str());
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(doubleTab).Append("if (proxy == nullptr) {\n");
|
||||
sb.Append(doubleTab + TAB).Append("HDF_LOGW(\"Reconnect failed : input proxy is null\");\n");
|
||||
sb.Append(doubleTab + TAB).Append("return HDF_FAILURE;\n");
|
||||
sb.Append(doubleTab).Append("}\n");
|
||||
sb.Append(doubleTab).AppendFormat("using namespace %s;\n", devmgrVersionName_.c_str());
|
||||
sb.Append(doubleTab).Append("proxy->isReconnected_ = false;\n");
|
||||
sb.Append(doubleTab).Append("auto iServMgr = IServiceManager::Get();\n");
|
||||
sb.Append(doubleTab).Append("if (iServMgr == nullptr) {\n");
|
||||
sb.Append(doubleTab + TAB).Append("HDF_LOGW(\"Reconnect failed : iServMgr is null\");\n");
|
||||
sb.Append(doubleTab + TAB).Append("return HDF_FAILURE;\n");
|
||||
sb.Append(doubleTab).Append("};\n");
|
||||
sb.Append(doubleTab).Append("proxy->reconnectRemote_ = ");
|
||||
sb.Append("iServMgr->GetService(proxy->serviceName_.c_str());\n");
|
||||
sb.Append(doubleTab).Append("if (proxy->reconnectRemote_ == nullptr) {\n");
|
||||
sb.Append(doubleTab + TAB).Append("HDF_LOGW(\"Reconnect failed : reconnectRemote_ is null\");\n");
|
||||
sb.Append(doubleTab + TAB).Append("return HDF_FAILURE;\n");
|
||||
sb.Append(doubleTab).Append("}\n");
|
||||
sb.Append(doubleTab).Append("proxy->servMgr_ = ");
|
||||
sb.Append("OHOS::HDI::hdi_objcast<IServiceManager>(iServMgr);\n");
|
||||
sb.Append(doubleTab).Append("if (proxy->servMgr_ == nullptr) {\n");
|
||||
sb.Append(doubleTab + TAB).Append("HDF_LOGE(\"%{public}s:get IServiceManager failed!\", __func__);\n");
|
||||
sb.Append(doubleTab + TAB).Append("return HDF_FAILURE;\n");
|
||||
sb.Append(doubleTab).Append("}\n");
|
||||
sb.Append(doubleTab).Append("proxy->servMgr_->AddDeathRecipient(\n");
|
||||
sb.Append(doubleTab + TAB).AppendFormat("new %s::%s(proxy));\n",
|
||||
EmitDefinitionByInterface(interface_, proxyName_).c_str(), devmgrDeathRecipientName_.c_str());
|
||||
sb.Append(doubleTab).Append("proxy->isReconnected_ = true;\n");
|
||||
sb.Append(doubleTab).Append("return HDF_SUCCESS;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
std::string CppClientProxyCodeEmitter::GetNameSpaceByInterface(AutoPtr<ASTInterfaceType> interface,
|
||||
const std::string &name)
|
||||
{
|
||||
std::string value = EmitDefinitionByInterface(interface, name);
|
||||
if (value.empty()) {
|
||||
return "";
|
||||
}
|
||||
size_t index = value.rfind(':');
|
||||
return (index == std::string::npos) ? value.substr(0) : value.substr(0, index + 1);
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyPassthroughtLoadImpl(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("if (isStub) {\n");
|
||||
|
||||
if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
|
||||
sb.Append(prefix + TAB).Append("std::string desc = ");
|
||||
sb.Append("std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(");
|
||||
sb.AppendFormat("%s::GetDescriptor());\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
} else {
|
||||
sb.Append(prefix + TAB).AppendFormat("std::string desc = Str16ToStr8(%s::GetDescriptor());\n",
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
}
|
||||
sb.Append(prefix + TAB).Append("void *impl = LoadHdiImpl(desc.c_str(), ");
|
||||
sb.AppendFormat("serviceName == \"%s\" ? \"service\" : serviceName.c_str());\n", FileName(implName_).c_str());
|
||||
sb.Append(prefix + TAB).Append("if (impl == nullptr) {\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"failed to load hdi impl %{public}s\", desc.data());\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n");
|
||||
|
||||
if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
|
||||
sb.Append(prefix + TAB).AppendFormat("return std::shared_ptr<%s>(reinterpret_cast<%s *>(impl));\n",
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
} else {
|
||||
sb.Append(prefix + TAB).AppendFormat("return reinterpret_cast<%s *>(impl);\n",
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
}
|
||||
sb.Append(prefix).Append("}\n\n");
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyMethodImpls(StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
AutoPtr<ASTInterfaceType> interface = interface_;
|
||||
AutoPtr<ASTInterfaceType> metaInterface = interface_;
|
||||
while (interface != nullptr) {
|
||||
for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
EmitProxyMethodImpl(interface, method, sb, prefix);
|
||||
sb.Append("\n");
|
||||
}
|
||||
interface = interface->GetExtendsInterface();
|
||||
if (interface != nullptr) {
|
||||
metaInterface = interface;
|
||||
}
|
||||
}
|
||||
AutoPtr<ASTMethod> verMethod = interface_->GetVersionMethod();
|
||||
EmitProxyMethodImpl(metaInterface, verMethod, sb, prefix);
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
sb.Append("\n");
|
||||
EmitProxyStaticMethodImpl(method, sb, prefix);
|
||||
}
|
||||
if (interface_->GetExtendsInterface() == nullptr) {
|
||||
sb.Append("\n");
|
||||
EmitProxyStaticMethodImpl(interface_->GetVersionMethod(), sb, prefix);
|
||||
}
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyIsProxyMethodImpl(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).Append("inline bool IsProxy() override\n");
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB).Append("return true;\n");
|
||||
sb.Append(prefix).Append("}\n\n");
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyCastFromMethodImpls(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
AutoPtr<ASTInterfaceType> interface = interface_->GetExtendsInterface();
|
||||
while (interface != nullptr) {
|
||||
EmitProxyCastFromMethodImpl(interface, sb, prefix);
|
||||
sb.Append(prefix).Append("\n");
|
||||
interface = interface->GetExtendsInterface();
|
||||
}
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyCastFromMethodImpl(const AutoPtr<ASTInterfaceType> interface,
|
||||
StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
std::string currentInterface = EmitDefinitionByInterface(interface_, interfaceName_);
|
||||
std::string parentInterface = EmitDefinitionByInterface(interface, interfaceName_);
|
||||
|
||||
sb.Append(prefix).AppendFormat("sptr<%s> %s::CastFrom(const sptr<%s> &parent)\n",
|
||||
currentInterface.c_str(), currentInterface.c_str(), parentInterface.c_str());
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("return CastFromTemplate<%s, %s>(parent);\n",
|
||||
currentInterface.c_str(), parentInterface.c_str());
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyCastFromMethodImplTemplate(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
std::string serMajorName = "serMajorVer";
|
||||
std::string serMinorName = "serMinorVer";
|
||||
|
||||
sb.Append(prefix).Append("template<typename ChildType, typename ParentType>\n");
|
||||
sb.Append(prefix).Append("static sptr<ChildType> CastFromTemplate(const sptr<ParentType> &parent)\n");
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB).Append("if (parent == nullptr) {\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:parent is nullptr!\", __func__);\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n\n");
|
||||
|
||||
sb.Append(prefix + TAB).Append("if (!parent->IsProxy()) {\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:not proxy, not support castfrom!\", __func__);\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n\n");
|
||||
|
||||
sb.Append(prefix + TAB).AppendFormat("sptr<IRemoteObject> remote = OHOS::HDI::hdi_objcast<ParentType>(parent);\n");
|
||||
sb.Append(prefix + TAB).Append("if (remote == nullptr) {\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:hdi_objcast failed!\", __func__);\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n\n");
|
||||
|
||||
sb.Append(prefix + TAB).AppendFormat("sptr<ChildType> proxy = OHOS::HDI::hdi_facecast<ChildType>(remote);\n");
|
||||
sb.Append(prefix + TAB).Append("if (proxy == nullptr) {\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:hdi_facecast failed!\", __func__);\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n\n");
|
||||
|
||||
sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMajorName.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMinorName.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("int32_t %s = proxy->GetVersion(%s, %s);\n",
|
||||
HdiTypeEmitter::errorCodeName_.c_str(), serMajorName.c_str(), serMinorName.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("if (%s != HDF_SUCCESS) {\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get version failed!\", __func__);\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n\n");
|
||||
|
||||
sb.Append(prefix + TAB).AppendFormat("if (%s != %d) {\n", serMajorName.c_str(), ast_->GetMajorVer());
|
||||
sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:check version failed! ");
|
||||
sb.Append("version of service:%u.%u");
|
||||
sb.AppendFormat(", version of client:%d.%d\", __func__, ", ast_->GetMajorVer(), ast_->GetMinorVer());
|
||||
sb.AppendFormat("%s, %s);\n", serMajorName.c_str(), serMinorName.c_str());
|
||||
sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n\n");
|
||||
|
||||
sb.Append(prefix + TAB).Append("return proxy;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyMethodImpl(const AutoPtr<ASTInterfaceType> interface,
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
if (method->GetParameterNumber() == 0) {
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"int32_t %s::%s()\n", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
|
||||
} else {
|
||||
StringBuilder paramStr;
|
||||
paramStr.Append(prefix).AppendFormat(
|
||||
"int32_t %s::%s(", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
EmitInterfaceMethodParameter(param, paramStr, "");
|
||||
if (i + 1 < method->GetParameterNumber()) {
|
||||
paramStr.Append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
paramStr.Append(")");
|
||||
|
||||
sb.Append(SpecificationParam(paramStr, prefix + TAB));
|
||||
sb.Append("\n");
|
||||
}
|
||||
EmitProxyMethodBody(interface, method, sb, prefix);
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyStaticMethodImpl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
if (method->GetParameterNumber() == 0) {
|
||||
sb.Append(prefix).AppendFormat("int32_t %s::%s_(const sptr<IRemoteObject> remote)\n",
|
||||
EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
|
||||
} else {
|
||||
StringBuilder paramStr;
|
||||
paramStr.Append(prefix).AppendFormat(
|
||||
"int32_t %s::%s_(", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
EmitInterfaceMethodParameter(param, paramStr, "");
|
||||
paramStr.Append(", ");
|
||||
}
|
||||
|
||||
paramStr.Append("const sptr<IRemoteObject> remote)");
|
||||
sb.Append(SpecificationParam(paramStr, prefix + TAB));
|
||||
sb.Append("\n");
|
||||
}
|
||||
EmitProxyStaticMethodBody(method, sb, prefix);
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyMethodBody(const AutoPtr<ASTInterfaceType> interface,
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("return %s::%s_(",
|
||||
EmitDefinitionByInterface(interface, proxyName_).c_str(), method->GetName().c_str());
|
||||
if (method->GetParameterNumber() > 0) {
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
sb.Append(param->GetName().c_str());
|
||||
sb.Append(", ");
|
||||
}
|
||||
}
|
||||
if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
|
||||
sb.Append("GetCurrentRemote());\n");
|
||||
} else {
|
||||
sb.Append("Remote());\n");
|
||||
}
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitProxyStaticMethodBody(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
std::string option = method->IsOneWay() ? "MessageOption::TF_ASYNC" : "MessageOption::TF_SYNC";
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("MessageParcel %s;\n", HdiTypeEmitter::dataParcelName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("MessageParcel %s;\n", HdiTypeEmitter::replyParcelName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("MessageOption %s(%s);\n", optionName_.c_str(), option.c_str());
|
||||
sb.Append("\n");
|
||||
|
||||
// write interface token
|
||||
EmitWriteInterfaceToken(HdiTypeEmitter::dataParcelName_, sb, prefix + TAB);
|
||||
sb.Append("\n");
|
||||
|
||||
EmitWriteFlagOfNeedSetMem(method, HdiTypeEmitter::dataParcelName_, sb, prefix + TAB);
|
||||
|
||||
if (method->GetParameterNumber() > 0) {
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
if (param->GetAttribute() == ASTParamAttr::PARAM_IN) {
|
||||
EmitWriteMethodParameter(param, HdiTypeEmitter::dataParcelName_, sb, prefix + TAB);
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.Append(prefix + TAB).AppendFormat("if (remote == nullptr) {\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid remote object!\", __func__);\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("int32_t %s = remote->SendRequest(%s, %s, %s, %s);\n",
|
||||
HdiTypeEmitter::errorCodeName_.c_str(), EmitMethodCmdID(method).c_str(),
|
||||
HdiTypeEmitter::dataParcelName_.c_str(), HdiTypeEmitter::replyParcelName_.c_str(), optionName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("if (%s != HDF_SUCCESS) {\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB + TAB).AppendFormat(
|
||||
"HDF_LOGE(\"%%{public}s failed, error code is %%{public}d\", __func__, %s);\n",
|
||||
HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB + TAB).AppendFormat("return %s;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB).Append("}\n");
|
||||
|
||||
if (!method->IsOneWay()) {
|
||||
sb.Append("\n");
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
if (param->GetAttribute() == ASTParamAttr::PARAM_OUT) {
|
||||
EmitReadMethodParameter(param, TypeMode::PARAM_OUT, sb, prefix + TAB);
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sb.Append(prefix + TAB).AppendFormat("return %s;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitWriteInterfaceToken(
|
||||
const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("if (!%s.WriteInterfaceToken(%s::GetDescriptor())) {\n", parcelName.c_str(),
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
sb.Append(prefix + TAB)
|
||||
.AppendFormat("HDF_LOGE(\"%%{public}s: failed to write interface descriptor!\", __func__);\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitWriteFlagOfNeedSetMem(const AutoPtr<ASTMethod> &method,
|
||||
const std::string &dataBufName, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
if (NeedFlag(method)) {
|
||||
sb.Append(prefix).AppendFormat("if (!%s.WriteBool(false)) {\n", dataBufName.c_str());
|
||||
sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s:failed to write flag of memory setting!\", __func__);\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n");
|
||||
sb.Append(prefix).Append("}\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
void CppClientProxyCodeEmitter::EmitUtilMethods(StringBuilder &sb, bool isDecl)
|
||||
{
|
||||
UtilMethodMap methods;
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
|
||||
if (param->GetAttribute() == ASTParamAttr::PARAM_IN) {
|
||||
typeEmitter->EmitCppWriteMethods(methods, "", "", isDecl);
|
||||
} else {
|
||||
typeEmitter->EmitCppReadMethods(methods, "", "", isDecl);
|
||||
}
|
||||
}
|
||||
}
|
||||
EmitUtilMethodMap(sb, methods);
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
126
idl_tool_2/codegen/HDI/cpp/cpp_client_proxy_code_emitter.h
Normal file
126
idl_tool_2/codegen/HDI/cpp/cpp_client_proxy_code_emitter.h
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_CPP_CLIENT_PROXY_CODE_EMITTER_H
|
||||
#define OHOS_IDL_CPP_CLIENT_PROXY_CODE_EMITTER_H
|
||||
|
||||
#include "hdi_cpp_code_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
class CppClientProxyCodeEmitter : public HDICppCodeEmitter {
|
||||
public:
|
||||
CppClientProxyCodeEmitter() : HDICppCodeEmitter()
|
||||
{
|
||||
devmgrDeathRecipientName_ = "IServiceManagerDeathRecipient";
|
||||
devmgrVersionName_ = "OHOS::HDI::ServiceManager::V1_0";
|
||||
}
|
||||
|
||||
~CppClientProxyCodeEmitter() override = default;
|
||||
|
||||
protected:
|
||||
std::string devmgrDeathRecipientName_;
|
||||
std::string devmgrVersionName_;
|
||||
|
||||
private:
|
||||
bool ResolveDirectory(const std::string &targetDirectory) override;
|
||||
|
||||
void EmitCode() override;
|
||||
|
||||
void EmitProxyHeaderFile();
|
||||
|
||||
void EmitProxyHeaderInclusions(StringBuilder &sb);
|
||||
|
||||
void GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const;
|
||||
|
||||
void GetSourceOtherFileInclusions(HeaderFile::HeaderFileSet &headerFiles) const;
|
||||
|
||||
void EmitProxyDecl(StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitProxyConstructor(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitProxyMethodDecls(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitProxyMethodDecl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitProxyConstants(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitPassthroughProxySourceFile();
|
||||
|
||||
void EmitPassthroughProxySourceInclusions(StringBuilder &sb);
|
||||
|
||||
void EmitPassthroughGetInstanceMethodImpl(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitProxySourceFile();
|
||||
|
||||
void EmitProxySourceInclusions(StringBuilder &sb);
|
||||
|
||||
void GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const;
|
||||
|
||||
void EmitGetMethodImpl(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitGetInstanceMethodImpl(StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitProxyPassthroughtLoadImpl(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitProxyMethodImpls(StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitProxyMethodImpl(const AutoPtr<ASTInterfaceType> interface, const AutoPtr<ASTMethod> &method,
|
||||
StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitProxyMethodBody(const AutoPtr<ASTInterfaceType> interface, const AutoPtr<ASTMethod> &method,
|
||||
StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitWriteInterfaceToken(const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitWriteFlagOfNeedSetMem(const AutoPtr<ASTMethod> &method, const std::string &dataBufName, StringBuilder &sb,
|
||||
const std::string &prefix) const;
|
||||
|
||||
void EmitUtilMethods(StringBuilder &sb, bool isDecl) override;
|
||||
|
||||
void EmitProxyStaticMethodDecl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitProxyStaticMethodImpl(const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitProxyStaticMethodBody(const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitProxyIsProxyMethodImpl(StringBuilder &sb, const std::string &prefix) const;
|
||||
void EmitProxyCastFromMethodImpls(StringBuilder &sb, const std::string &prefix) const;
|
||||
void EmitProxyCastFromMethodImpl(const AutoPtr<ASTInterfaceType> interface, StringBuilder &sb,
|
||||
const std::string &prefix) const;
|
||||
void EmitProxyCastFromMethodImplTemplate(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
std::string GetNameSpaceByInterface(AutoPtr<ASTInterfaceType> interface, const std::string &name);
|
||||
|
||||
void EmitProxyDevmgrDeathRecipient(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitProxyPublicMembers(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitProxyDevmgrDeathCallBack(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitProxyReconnectMethodDecl(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitProxyGetRemoteMethodDecl(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitGetInstanceMethodInitProxyImpl(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitProxyCppReconnectMethodImpl(StringBuilder &sb, const std::string &prefix) const;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_CPP_CLIENT_PROXY_CODE_EMITTER_H
|
361
idl_tool_2/codegen/HDI/cpp/cpp_custom_types_code_emitter.cpp
Normal file
361
idl_tool_2/codegen/HDI/cpp/cpp_custom_types_code_emitter.cpp
Normal file
@ -0,0 +1,361 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "cpp_custom_types_code_emitter.h"
|
||||
#include "util/file.h"
|
||||
#include "util/logger.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
bool CppCustomTypesCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
|
||||
{
|
||||
if (ast_->GetASTFileType() != ASTFileType::AST_TYPES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
directory_ = GetFileParentPath(targetDirectory);
|
||||
if (!File::CreateParentDir(directory_)) {
|
||||
Logger::E("CppCustomTypesCodeEmitter", "Create '%s' failed!", directory_.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::EmitCode()
|
||||
{
|
||||
switch (mode_) {
|
||||
case GenMode::PASSTHROUGH: {
|
||||
EmitPassthroughCustomTypesHeaderFile();
|
||||
break;
|
||||
}
|
||||
case GenMode::IPC: {
|
||||
EmitCustomTypesHeaderFile();
|
||||
EmitCustomTypesSourceFile();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::EmitPassthroughCustomTypesHeaderFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(baseName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
std::string marcoName = StringHelper::Format("%s.%s", ast_->GetPackageName().c_str(), baseName_.c_str());
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitHeadMacro(sb, marcoName);
|
||||
sb.Append("\n");
|
||||
EmitPassthroughHeaderFileInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitBeginNamespace(sb);
|
||||
sb.Append("\n");
|
||||
EmitUsingNamespace(sb);
|
||||
sb.Append("\n");
|
||||
EmitCustomTypeDecls(sb);
|
||||
EmitEndNamespace(sb);
|
||||
sb.Append("\n");
|
||||
EmitTailMacro(sb, marcoName);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::EmitPassthroughHeaderFileInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
headerFiles.emplace(HeaderFileType::CPP_STD_HEADER_FILE, "cstdbool");
|
||||
headerFiles.emplace(HeaderFileType::CPP_STD_HEADER_FILE, "cstdint");
|
||||
GetStdlibInclusions(headerFiles);
|
||||
GetImportInclusions(headerFiles);
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::EmitCustomTypesHeaderFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(baseName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
std::string marcoName = StringHelper::Format("%s.%s", ast_->GetPackageName().c_str(), baseName_.c_str());
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitHeadMacro(sb, marcoName);
|
||||
sb.Append("\n");
|
||||
EmitHeaderFileInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitInterfaceBuffSizeMacro(sb);
|
||||
sb.Append("\n");
|
||||
EmitForwardDeclaration(sb);
|
||||
sb.Append("\n");
|
||||
EmitBeginNamespace(sb);
|
||||
sb.Append("\n");
|
||||
EmitUsingNamespace(sb);
|
||||
sb.Append("\n");
|
||||
EmitCustomTypeDecls(sb);
|
||||
sb.Append("\n");
|
||||
EmitCustomTypeFuncDecl(sb);
|
||||
sb.Append("\n");
|
||||
EmitEndNamespace(sb);
|
||||
sb.Append("\n");
|
||||
EmitTailMacro(sb, marcoName);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::EmitHeaderFileInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
headerFiles.emplace(HeaderFileType::CPP_STD_HEADER_FILE, "cstdbool");
|
||||
headerFiles.emplace(HeaderFileType::CPP_STD_HEADER_FILE, "cstdint");
|
||||
GetStdlibInclusions(headerFiles);
|
||||
GetImportInclusions(headerFiles);
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::EmitForwardDeclaration(StringBuilder &sb) const
|
||||
{
|
||||
sb.Append("namespace OHOS {\n");
|
||||
sb.Append("class MessageParcel;\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::EmitUsingNamespace(StringBuilder &sb)
|
||||
{
|
||||
sb.Append("using namespace OHOS;\n");
|
||||
EmitImportUsingNamespace(sb);
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::EmitCustomTypeDecls(StringBuilder &sb) const
|
||||
{
|
||||
for (size_t i = 0; i < ast_->GetTypeDefinitionNumber(); i++) {
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(ast_->GetTypeDefintion(i));
|
||||
sb.Append(typeEmitter->EmitCppTypeDecl()).Append("\n");
|
||||
if (i + 1 < ast_->GetTypeDefinitionNumber()) {
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::EmitCustomTypeFuncDecl(StringBuilder &sb) const
|
||||
{
|
||||
for (size_t i = 0; i < ast_->GetTypeDefinitionNumber(); i++) {
|
||||
AutoPtr<ASTType> type = ast_->GetTypeDefintion(i);
|
||||
if (type->GetTypeKind() == TypeKind::TYPE_STRUCT) {
|
||||
EmitCustomTypeMarshallFuncDecl(sb, type);
|
||||
if (i + 1 < ast_->GetTypeDefinitionNumber()) {
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::EmitCustomTypeMarshallFuncDecl(StringBuilder &sb, const AutoPtr<ASTType> &type) const
|
||||
{
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
|
||||
std::string objName("dataBlock");
|
||||
sb.AppendFormat("bool %sBlockMarshalling(OHOS::MessageParcel &data, const %s& %s);\n\n", type->GetName().c_str(),
|
||||
typeEmitter->EmitCppType().c_str(), objName.c_str());
|
||||
sb.AppendFormat("bool %sBlockUnmarshalling(OHOS::MessageParcel &data, %s& %s);\n", type->GetName().c_str(),
|
||||
typeEmitter->EmitCppType().c_str(), objName.c_str());
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::EmitCustomTypesSourceFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(baseName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitSourceFileInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitBeginNamespace(sb);
|
||||
sb.Append("\n");
|
||||
EmitUtilMethods(sb, true);
|
||||
sb.Append("\n");
|
||||
EmitUtilMethods(sb, false);
|
||||
sb.Append("\n");
|
||||
EmitCustomTypeDataProcess(sb);
|
||||
sb.Append("\n");
|
||||
EmitEndNamespace(sb);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::EmitSourceFileInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
|
||||
headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(baseName_));
|
||||
GetSourceOtherLibInclusions(headerFiles);
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
|
||||
{
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_parcel");
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::EmitCustomTypeDataProcess(StringBuilder &sb) const
|
||||
{
|
||||
for (size_t i = 0; i < ast_->GetTypeDefinitionNumber(); i++) {
|
||||
AutoPtr<ASTType> type = ast_->GetTypeDefintion(i);
|
||||
if (type->GetTypeKind() == TypeKind::TYPE_STRUCT) {
|
||||
AutoPtr<ASTStructType> structType = dynamic_cast<ASTStructType *>(type.Get());
|
||||
EmitCustomTypeMarshallingImpl(sb, structType);
|
||||
EmitCustomTypeUnmarshallingImpl(sb, structType);
|
||||
if (i + 1 < ast_->GetTypeDefinitionNumber()) {
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::EmitCustomTypeMarshallingImpl(
|
||||
StringBuilder &sb, const AutoPtr<ASTStructType> &type) const
|
||||
{
|
||||
std::string typeName = GetTypeEmitter(type.Get())->EmitCppType();
|
||||
std::string objName("dataBlock");
|
||||
|
||||
sb.AppendFormat("bool %sBlockMarshalling(OHOS::MessageParcel& data, const %s& %s)\n", type->GetName().c_str(),
|
||||
typeName.c_str(), objName.c_str());
|
||||
sb.Append("{\n");
|
||||
|
||||
if (type->IsPod()) {
|
||||
sb.Append(TAB).AppendFormat("if (!data.WriteUnpadBuffer((const void*)&%s, sizeof(%s))) {\n",
|
||||
objName.c_str(), typeName.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("return false;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
} else {
|
||||
for (size_t i = 0; i < type->GetMemberNumber(); i++) {
|
||||
std::string memberName = type->GetMemberName(i);
|
||||
std::string name = StringHelper::Format("%s.%s", objName.c_str(), memberName.c_str());
|
||||
GetTypeEmitter(type->GetMemberType(i))->EmitCppMarshalling("data", name, sb, TAB);
|
||||
if (i + 1 < type->GetMemberNumber()) {
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sb.Append(TAB).Append("return true;\n");
|
||||
sb.Append("}\n\n");
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::EmitCustomTypeUnmarshallingImpl(
|
||||
StringBuilder &sb, const AutoPtr<ASTStructType> &type) const
|
||||
{
|
||||
std::string typeName = GetTypeEmitter(type.Get())->EmitCppType();
|
||||
std::string objName("dataBlock");
|
||||
|
||||
sb.AppendFormat("bool %sBlockUnmarshalling(OHOS::MessageParcel& data, %s& %s)\n", type->GetName().c_str(),
|
||||
typeName.c_str(), objName.c_str());
|
||||
sb.Append("{\n");
|
||||
|
||||
if (type->IsPod()) {
|
||||
std::string objPtrName = StringHelper::Format("%sPtr", objName.c_str());
|
||||
sb.Append(TAB).AppendFormat("const %s *%s = reinterpret_cast<const %s*>(data.ReadUnpadBuffer(sizeof(%s)));\n",
|
||||
typeName.c_str(), objPtrName.c_str(), typeName.c_str(), typeName.c_str());
|
||||
sb.Append(TAB).AppendFormat("if (%s == NULL) {\n", objPtrName.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("return false;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
sb.Append(TAB).AppendFormat("if (memcpy_s(&%s, sizeof(%s), %s, sizeof(%s)) != EOK) {\n", objName.c_str(),
|
||||
typeName.c_str(), objPtrName.c_str(), typeName.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("return false;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
} else {
|
||||
for (size_t i = 0; i < type->GetMemberNumber(); i++) {
|
||||
AutoPtr<ASTType> memberType = type->GetMemberType(i);
|
||||
std::string memberName = type->GetMemberName(i);
|
||||
std::string name = StringHelper::Format("%s.%s", objName.c_str(), memberName.c_str());
|
||||
if (i > 0) {
|
||||
sb.Append("\n");
|
||||
}
|
||||
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(memberType);
|
||||
if (memberType->GetTypeKind() == TypeKind::TYPE_UNION) {
|
||||
std::string cpName = StringHelper::Format("%sCp", memberName.c_str());
|
||||
typeEmitter->EmitCppUnMarshalling("data", cpName, sb, TAB);
|
||||
sb.Append(TAB).AppendFormat("if (memcpy_s(&%s, sizeof(%s), %s, sizeof(%s)) != EOK) {\n",
|
||||
name.c_str(), typeEmitter->EmitCppType().c_str(), cpName.c_str(),
|
||||
typeEmitter->EmitCppType().c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to memcpy %s\", __func__);\n",
|
||||
name.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("return false;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
} else if (memberType->GetTypeKind() == TypeKind::TYPE_STRING) {
|
||||
std::string cpName = StringHelper::Format("%sCp", memberName.c_str());
|
||||
typeEmitter->EmitCppUnMarshalling("data", cpName, sb, TAB);
|
||||
sb.Append(TAB).AppendFormat("%s = %s;\n", name.c_str(), cpName.c_str());
|
||||
} else {
|
||||
typeEmitter->EmitCppUnMarshalling("data", name, sb, TAB);
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.Append(TAB).AppendFormat("return true;\n", objName.c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::EmitBeginNamespace(StringBuilder &sb)
|
||||
{
|
||||
std::vector<std::string> cppNamespaceVec = EmitCppNameSpaceVec(ast_->GetPackageName());
|
||||
for (const auto &nspace : cppNamespaceVec) {
|
||||
sb.AppendFormat("namespace %s {\n", nspace.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::EmitEndNamespace(StringBuilder &sb)
|
||||
{
|
||||
std::vector<std::string> cppNamespaceVec = EmitCppNameSpaceVec(ast_->GetPackageName());
|
||||
for (std::vector<std::string>::const_reverse_iterator nspaceIter = cppNamespaceVec.rbegin();
|
||||
nspaceIter != cppNamespaceVec.rend(); ++nspaceIter) {
|
||||
sb.AppendFormat("} // %s\n", nspaceIter->c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CppCustomTypesCodeEmitter::EmitUtilMethods(StringBuilder &sb, bool isDecl)
|
||||
{
|
||||
UtilMethodMap methods;
|
||||
for (const auto &typePair : ast_->GetTypes()) {
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(typePair.second);
|
||||
typeEmitter->EmitCppWriteMethods(methods, "", "", isDecl);
|
||||
typeEmitter->EmitCppReadMethods(methods, "", "", isDecl);
|
||||
}
|
||||
EmitUtilMethodMap(sb, methods);
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
73
idl_tool_2/codegen/HDI/cpp/cpp_custom_types_code_emitter.h
Normal file
73
idl_tool_2/codegen/HDI/cpp/cpp_custom_types_code_emitter.h
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_CPP_CUSTOM_TYPES_CODE_EMITTER_H
|
||||
#define OHOS_IDL_CPP_CUSTOM_TYPES_CODE_EMITTER_H
|
||||
|
||||
#include "hdi_cpp_code_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
class CppCustomTypesCodeEmitter : public HDICppCodeEmitter {
|
||||
public:
|
||||
CppCustomTypesCodeEmitter() : HDICppCodeEmitter() {}
|
||||
|
||||
~CppCustomTypesCodeEmitter() override = default;
|
||||
|
||||
private:
|
||||
bool ResolveDirectory(const std::string &targetDirectory) override;
|
||||
|
||||
void EmitCode() override;
|
||||
|
||||
void EmitPassthroughCustomTypesHeaderFile();
|
||||
|
||||
void EmitPassthroughHeaderFileInclusions(StringBuilder& sb);
|
||||
|
||||
void EmitCustomTypesHeaderFile();
|
||||
|
||||
void EmitHeaderFileInclusions(StringBuilder &sb);
|
||||
|
||||
void EmitForwardDeclaration(StringBuilder &sb) const;
|
||||
|
||||
void EmitUsingNamespace(StringBuilder &sb) override;
|
||||
|
||||
void EmitCustomTypeDecls(StringBuilder &sb) const;
|
||||
|
||||
void EmitCustomTypeFuncDecl(StringBuilder &sb) const;
|
||||
|
||||
void EmitCustomTypeMarshallFuncDecl(StringBuilder &sb, const AutoPtr<ASTType> &type) const;
|
||||
|
||||
void EmitCustomTypesSourceFile();
|
||||
|
||||
void EmitSourceFileInclusions(StringBuilder &sb);
|
||||
|
||||
void GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const;
|
||||
|
||||
void EmitCustomTypeDataProcess(StringBuilder &sb) const;
|
||||
|
||||
void EmitCustomTypeMarshallingImpl(StringBuilder &sb, const AutoPtr<ASTStructType> &type) const;
|
||||
|
||||
void EmitCustomTypeUnmarshallingImpl(StringBuilder &sb, const AutoPtr<ASTStructType> &type) const;
|
||||
|
||||
void EmitBeginNamespace(StringBuilder &sb) override;
|
||||
|
||||
void EmitEndNamespace(StringBuilder &sb) override;
|
||||
|
||||
void EmitUtilMethods(StringBuilder &sb, bool isDecl) override;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_CPP_CUSTOM_TYPES_CODE_EMITTER_H
|
292
idl_tool_2/codegen/HDI/cpp/cpp_interface_code_emitter.cpp
Normal file
292
idl_tool_2/codegen/HDI/cpp/cpp_interface_code_emitter.cpp
Normal file
@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "cpp_interface_code_emitter.h"
|
||||
#include "util/file.h"
|
||||
#include "util/logger.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
bool CppInterfaceCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
|
||||
{
|
||||
if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
|
||||
directory_ = GetFileParentPath(targetDirectory);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!File::CreateParentDir(directory_)) {
|
||||
Logger::E("CppInterfaceCodeEmitter", "Create '%s' failed!", directory_.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CppInterfaceCodeEmitter::EmitCode()
|
||||
{
|
||||
switch (mode_) {
|
||||
case GenMode::PASSTHROUGH:
|
||||
case GenMode::IPC: {
|
||||
EmitInterfaceHeaderFile();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CppInterfaceCodeEmitter::EmitInterfaceHeaderFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(interfaceName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitHeadMacro(sb, interfaceFullName_);
|
||||
sb.Append("\n");
|
||||
EmitInterfaceInclusions(sb);
|
||||
if (!Options::GetInstance().DoPassthrough()) {
|
||||
sb.Append("\n");
|
||||
EmitInterfaceBuffSizeMacro(sb);
|
||||
}
|
||||
sb.Append("\n");
|
||||
EmitBeginNamespace(sb);
|
||||
EmitUsingNamespace(sb);
|
||||
if (!Options::GetInstance().DoPassthrough()) {
|
||||
sb.Append("\n");
|
||||
if (interface_->GetExtendsInterface() == nullptr) {
|
||||
EmitInterfaceMethodCommands(sb, "");
|
||||
} else {
|
||||
EmitInterfaceMethodCommandsWithExtends(sb, "");
|
||||
}
|
||||
}
|
||||
sb.Append("\n");
|
||||
EmitInterfaceDefinition(sb);
|
||||
EmitEndNamespace(sb);
|
||||
sb.Append("\n");
|
||||
EmitTailMacro(sb, interfaceFullName_);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CppInterfaceCodeEmitter::EmitInterfaceInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
|
||||
GetStdlibInclusions(headerFiles);
|
||||
GetImportInclusions(headerFiles);
|
||||
GetHeaderOtherLibInclusions(headerFiles);
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CppInterfaceCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
|
||||
{
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
|
||||
headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "stdint");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_base");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
|
||||
}
|
||||
|
||||
void CppInterfaceCodeEmitter::EmitInterfaceVersionMacro(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("#define %s %u\n", majorVerName_.c_str(), ast_->GetMajorVer());
|
||||
sb.AppendFormat("#define %s %u\n", minorVerName_.c_str(), ast_->GetMinorVer());
|
||||
}
|
||||
|
||||
void CppInterfaceCodeEmitter::EmitInterfaceDefinition(StringBuilder &sb)
|
||||
{
|
||||
AutoPtr<ASTInterfaceType> interface = interface_->GetExtendsInterface();
|
||||
if (interface != nullptr) {
|
||||
sb.AppendFormat("class %s : public %s {\n", interfaceName_.c_str(),
|
||||
EmitDefinitionByInterface(interface, interfaceName_).c_str());
|
||||
} else {
|
||||
sb.AppendFormat("class %s : public HdiBase {\n", interfaceName_.c_str());
|
||||
}
|
||||
sb.Append("public:\n");
|
||||
EmitInterfaceDescriptor(sb, TAB);
|
||||
sb.Append("\n");
|
||||
EmitInterfaceDestruction(sb, TAB);
|
||||
sb.Append("\n");
|
||||
if (!interface_->IsSerializable()) {
|
||||
EmitGetMethodDecl(sb, TAB);
|
||||
sb.Append("\n");
|
||||
}
|
||||
if (interface_->GetExtendsInterface() != nullptr) {
|
||||
EmitCastFromDecl(sb, TAB);
|
||||
sb.Append("\n");
|
||||
}
|
||||
EmitInterfaceMethodsDecl(sb, TAB);
|
||||
sb.Append("\n");
|
||||
EmitGetDescMethod(sb, TAB);
|
||||
sb.Append("};\n");
|
||||
}
|
||||
|
||||
void CppInterfaceCodeEmitter::EmitGetDescMethod(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
AutoPtr<ASTInterfaceType> interface = interface_->GetExtendsInterface();
|
||||
if (interface == nullptr) {
|
||||
sb.Append(prefix).Append("virtual const std::u16string GetDesc()");
|
||||
} else {
|
||||
sb.Append(prefix).Append("const std::u16string GetDesc() override");
|
||||
}
|
||||
sb.Append("\n");
|
||||
sb.Append(prefix).Append("{").Append("\n");
|
||||
sb.Append(prefix + TAB).Append("return metaDescriptor_;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppInterfaceCodeEmitter::EmitInterfaceDescriptor(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
(void)prefix;
|
||||
sb.Append(TAB).AppendFormat("DECLARE_HDI_DESCRIPTOR(u\"%s\");\n", interfaceFullName_.c_str());
|
||||
}
|
||||
|
||||
void CppInterfaceCodeEmitter::EmitCastFromDecl(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
std::string currentInterface = EmitDefinitionByInterface(interface_, interfaceName_);
|
||||
|
||||
AutoPtr<ASTInterfaceType> interface = interface_->GetExtendsInterface();
|
||||
while (interface != nullptr) {
|
||||
std::string parentInterface = EmitDefinitionByInterface(interface, interfaceName_);
|
||||
sb.Append(prefix).AppendFormat("static sptr<%s> CastFrom(const sptr<%s> &parent);\n",
|
||||
currentInterface.c_str(), parentInterface.c_str());
|
||||
interface = interface->GetExtendsInterface();
|
||||
}
|
||||
}
|
||||
|
||||
void CppInterfaceCodeEmitter::EmitGetMethodDecl(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
std::string typeName = GetTypeEmitter(interface_.Get())->EmitCppType();
|
||||
sb.Append(prefix).AppendFormat("static %s Get(bool isStub = false);\n", typeName.c_str());
|
||||
sb.Append(prefix).AppendFormat("static %s Get(const std::string &serviceName, bool isStub = false);\n",
|
||||
typeName.c_str());
|
||||
}
|
||||
|
||||
void CppInterfaceCodeEmitter::EmitInterfaceDestruction(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("virtual ~%s() = default;\n", interface_->GetName().c_str());
|
||||
}
|
||||
|
||||
void CppInterfaceCodeEmitter::EmitInterfaceMethodsDecl(StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
EmitInterfaceMethodDecl(method, sb, prefix);
|
||||
sb.Append("\n");
|
||||
}
|
||||
|
||||
EmitInterfaceGetVersionMethod(sb, prefix);
|
||||
if (interface_->GetExtendsInterface() == nullptr) {
|
||||
sb.Append("\n");
|
||||
EmitInterfaceIsProxyMethod(sb, prefix);
|
||||
}
|
||||
}
|
||||
|
||||
void CppInterfaceCodeEmitter::EmitInterfaceMethodDecl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
if (interface_->GetExtendsInterface() != nullptr && method->IsOverload()) {
|
||||
sb.Append(prefix).AppendFormat("using %s::%s;\n",
|
||||
EmitDefinitionByInterface(interface_->GetExtendsInterface(), interfaceName_).c_str(),
|
||||
method->GetName().c_str());
|
||||
}
|
||||
|
||||
if (method->GetParameterNumber() == 0) {
|
||||
sb.Append(prefix).AppendFormat("virtual int32_t %s() = 0;\n", method->GetName().c_str());
|
||||
} else {
|
||||
StringBuilder paramStr;
|
||||
paramStr.Append(prefix).AppendFormat("virtual int32_t %s(", method->GetName().c_str());
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
EmitInterfaceMethodParameter(param, paramStr, "");
|
||||
if (i + 1 < method->GetParameterNumber()) {
|
||||
paramStr.Append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
paramStr.Append(") = 0;");
|
||||
sb.Append(SpecificationParam(paramStr, prefix + TAB));
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void CppInterfaceCodeEmitter::EmitInterfaceGetVersionMethod(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
AutoPtr<ASTMethod> method = interface_->GetVersionMethod();
|
||||
if (interface_->GetExtendsInterface() == nullptr) {
|
||||
sb.Append(prefix).AppendFormat("virtual int32_t %s(", method->GetName().c_str());
|
||||
} else {
|
||||
sb.Append(prefix).AppendFormat("int32_t %s(", method->GetName().c_str());
|
||||
}
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
EmitInterfaceMethodParameter(param, sb, "");
|
||||
if (i + 1 < method->GetParameterNumber()) {
|
||||
sb.Append(", ");
|
||||
}
|
||||
}
|
||||
sb.Append(")");
|
||||
if (interface_->GetExtendsInterface() != nullptr) {
|
||||
sb.Append(" override");
|
||||
}
|
||||
sb.Append("\n");
|
||||
sb.Append(prefix).Append("{\n");
|
||||
|
||||
AutoPtr<ASTParameter> majorParam = method->GetParameter(0);
|
||||
sb.Append(prefix + TAB).AppendFormat("%s = %d;\n", majorParam->GetName().c_str(), ast_->GetMajorVer());
|
||||
AutoPtr<ASTParameter> minorParam = method->GetParameter(1);
|
||||
sb.Append(prefix + TAB).AppendFormat("%s = %d;\n", minorParam->GetName().c_str(), ast_->GetMinorVer());
|
||||
|
||||
sb.Append(prefix + TAB).Append("return HDF_SUCCESS;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppInterfaceCodeEmitter::EmitInterfaceIsProxyMethod(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("virtual bool %s(", "IsProxy");
|
||||
sb.Append(")\n");
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB).Append("return false;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppInterfaceCodeEmitter::EmitInterfaceMethodCommandsWithExtends(StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
size_t extendMethods = 0;
|
||||
AutoPtr<ASTInterfaceType> interface = interface_->GetExtendsInterface();
|
||||
while (interface != nullptr) {
|
||||
extendMethods += interface->GetMethodNumber();
|
||||
interface = interface->GetExtendsInterface();
|
||||
}
|
||||
|
||||
sb.Append(prefix).AppendFormat("enum {\n");
|
||||
for (size_t i = 0; i < interface_->GetMethodNumber(); i++) {
|
||||
AutoPtr<ASTMethod> method = interface_->GetMethod(i);
|
||||
sb.Append(prefix + TAB)
|
||||
.Append(EmitMethodCmdID(method))
|
||||
.AppendFormat(" = %d", extendMethods + i + 1)
|
||||
.Append(",\n");
|
||||
}
|
||||
sb.Append(prefix).Append("};\n");
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
66
idl_tool_2/codegen/HDI/cpp/cpp_interface_code_emitter.h
Normal file
66
idl_tool_2/codegen/HDI/cpp/cpp_interface_code_emitter.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_CPP_INTERFACE_CODE_EMITTER_H
|
||||
#define OHOS_IDL_CPP_INTERFACE_CODE_EMITTER_H
|
||||
|
||||
#include "hdi_cpp_code_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
class CppInterfaceCodeEmitter : public HDICppCodeEmitter {
|
||||
public:
|
||||
CppInterfaceCodeEmitter() : HDICppCodeEmitter() {}
|
||||
|
||||
~CppInterfaceCodeEmitter() override = default;
|
||||
|
||||
private:
|
||||
bool ResolveDirectory(const std::string &targetDirectory) override;
|
||||
|
||||
void EmitCode() override;
|
||||
|
||||
void EmitInterfaceHeaderFile();
|
||||
|
||||
void EmitInterfaceInclusions(StringBuilder &sb);
|
||||
|
||||
void GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const;
|
||||
|
||||
void EmitInterfaceVersionMacro(StringBuilder &sb) const;
|
||||
|
||||
void EmitInterfaceDefinition(StringBuilder &sb);
|
||||
|
||||
void EmitInterfaceDescriptor(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitGetMethodDecl(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitInterfaceDestruction(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitInterfaceMethodsDecl(StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitInterfaceMethodDecl(const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitInterfaceGetVersionMethod(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitInterfaceIsProxyMethod(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitInterfaceMethodCommandsWithExtends(StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitGetDescMethod(StringBuilder &sb, const std::string &prefix) const;
|
||||
void EmitCastFromDecl(StringBuilder &sb, const std::string &prefix) const;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_CPP_INTERFACE_CODE_EMITTER_H
|
217
idl_tool_2/codegen/HDI/cpp/cpp_service_driver_code_emitter.cpp
Normal file
217
idl_tool_2/codegen/HDI/cpp/cpp_service_driver_code_emitter.cpp
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "cpp_service_driver_code_emitter.h"
|
||||
#include "util/file.h"
|
||||
#include "util/logger.h"
|
||||
#include "util/options.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
bool CppServiceDriverCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
|
||||
{
|
||||
if (ast_->GetASTFileType() != ASTFileType::AST_IFACE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
directory_ = GetFileParentPath(targetDirectory);
|
||||
if (!File::CreateParentDir(directory_)) {
|
||||
Logger::E("CppServiceDriverCodeEmitter", "Create '%s' failed!", directory_.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CppServiceDriverCodeEmitter::EmitCode()
|
||||
{
|
||||
if (mode_ == GenMode::IPC) {
|
||||
if (!interface_->IsSerializable()) {
|
||||
EmitDriverSourceFile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CppServiceDriverCodeEmitter::EmitDriverSourceFile()
|
||||
{
|
||||
std::string filePath = File::AdapterPath(
|
||||
StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(baseName_ + "Driver").c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitDriverInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitLogTagMacro(sb, FileName(baseName_ + "Driver"));
|
||||
sb.Append("\n");
|
||||
EmitDriverUsings(sb);
|
||||
sb.Append("\n");
|
||||
EmitDriverServiceDecl(sb);
|
||||
sb.Append("\n");
|
||||
EmitDriverDispatch(sb);
|
||||
sb.Append("\n");
|
||||
EmitDriverInit(sb);
|
||||
sb.Append("\n");
|
||||
EmitDriverBind(sb);
|
||||
sb.Append("\n");
|
||||
EmitDriverRelease(sb);
|
||||
sb.Append("\n");
|
||||
EmitDriverEntryDefinition(sb);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CppServiceDriverCodeEmitter::EmitDriverInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_device_desc");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_sbuf_ipc");
|
||||
headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(stubName_));
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CppServiceDriverCodeEmitter::EmitDriverUsings(StringBuilder &sb)
|
||||
{
|
||||
std::string nspace = EmitPackageToNameSpace(interface_->GetNamespace()->ToString());
|
||||
sb.AppendFormat("using namespace %s;\n", nspace.c_str());
|
||||
}
|
||||
|
||||
void CppServiceDriverCodeEmitter::EmitDriverServiceDecl(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("struct Hdf%sHost {\n", baseName_.c_str());
|
||||
sb.Append(TAB).Append("struct IDeviceIoService ioService;\n");
|
||||
sb.Append(TAB).Append("OHOS::sptr<OHOS::IRemoteObject> stub;\n");
|
||||
sb.Append("};\n");
|
||||
}
|
||||
|
||||
void CppServiceDriverCodeEmitter::EmitDriverDispatch(StringBuilder &sb) const
|
||||
{
|
||||
std::string objName = StringHelper::Format("hdf%sHost", baseName_.c_str());
|
||||
sb.AppendFormat("static int32_t %sDriverDispatch(", baseName_.c_str());
|
||||
sb.Append("struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data,\n");
|
||||
sb.Append(TAB).Append("struct HdfSBuf *reply)\n");
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).AppendFormat("auto *%s = CONTAINER_OF(", objName.c_str());
|
||||
sb.AppendFormat("client->device->service, struct Hdf%sHost, ioService);\n\n", baseName_.c_str());
|
||||
|
||||
sb.Append(TAB).Append("OHOS::MessageParcel *dataParcel = nullptr;\n");
|
||||
sb.Append(TAB).Append("OHOS::MessageParcel *replyParcel = nullptr;\n");
|
||||
sb.Append(TAB).Append("OHOS::MessageOption option;\n\n");
|
||||
|
||||
sb.Append(TAB).Append("if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: invalid data sbuf object to dispatch\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
|
||||
sb.Append(TAB).Append("}\n");
|
||||
sb.Append(TAB).Append("if (SbufToParcel(reply, &replyParcel) != HDF_SUCCESS) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: invalid reply sbuf object to dispatch\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
|
||||
sb.Append(TAB).AppendFormat(
|
||||
"return %s->stub->SendRequest(cmdId, *dataParcel, *replyParcel, option);\n", objName.c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CppServiceDriverCodeEmitter::EmitDriverInit(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("static int Hdf%sDriverInit(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("HDF_LOGI(\"%{public}s: driver init start\", __func__);\n");
|
||||
sb.Append(TAB).Append("return HDF_SUCCESS;\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CppServiceDriverCodeEmitter::EmitDriverBind(StringBuilder &sb) const
|
||||
{
|
||||
std::string objName = StringHelper::Format("hdf%sHost", baseName_.c_str());
|
||||
sb.AppendFormat("static int Hdf%sDriverBind(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("HDF_LOGI(\"%{public}s: driver bind start\", __func__);\n");
|
||||
|
||||
sb.Append(TAB).AppendFormat("auto *%s = new (std::nothrow) Hdf%sHost;\n", objName.c_str(), baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("if (%s == nullptr) {\n", objName.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat(
|
||||
"HDF_LOGE(\"%%{public}s: failed to create create Hdf%sHost object\", __func__);\n", baseName_.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("return HDF_FAILURE;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
|
||||
sb.Append(TAB).AppendFormat("%s->ioService.Dispatch = %sDriverDispatch;\n", objName.c_str(), baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("%s->ioService.Open = NULL;\n", objName.c_str());
|
||||
sb.Append(TAB).AppendFormat("%s->ioService.Release = NULL;\n\n", objName.c_str());
|
||||
|
||||
sb.Append(TAB).AppendFormat(
|
||||
"auto serviceImpl = %s::Get(true);\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
sb.Append(TAB).Append("if (serviceImpl == nullptr) {\n");
|
||||
sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: failed to get of implement service\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("delete %s;\n", objName.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("return HDF_FAILURE;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
|
||||
sb.Append(TAB).AppendFormat("%s->stub = OHOS::HDI::ObjectCollector::GetInstance().", objName.c_str());
|
||||
sb.Append("GetOrNewObject(serviceImpl,\n");
|
||||
sb.Append(TAB).Append(TAB).AppendFormat(
|
||||
"%s::GetDescriptor());\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
sb.Append(TAB).AppendFormat("if (%s->stub == nullptr) {\n", objName.c_str());
|
||||
sb.Append(TAB).Append(TAB).Append("HDF_LOGE(\"%{public}s: failed to get stub object\", __func__);\n");
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("delete %s;\n", objName.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("return HDF_FAILURE;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
|
||||
sb.Append(TAB).AppendFormat("deviceObject->service = &%s->ioService;\n", objName.c_str());
|
||||
sb.Append(TAB).Append("return HDF_SUCCESS;\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CppServiceDriverCodeEmitter::EmitDriverRelease(StringBuilder &sb) const
|
||||
{
|
||||
std::string objName = StringHelper::Format("hdf%sHost", baseName_.c_str());
|
||||
sb.AppendFormat("static void Hdf%sDriverRelease(struct HdfDeviceObject *deviceObject)\n", baseName_.c_str());
|
||||
sb.Append("{\n");
|
||||
sb.Append(TAB).Append("HDF_LOGI(\"%{public}s: driver release start\", __func__);\n");
|
||||
sb.Append(TAB).AppendFormat("if (deviceObject->service == nullptr) {\n");
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("return;\n");
|
||||
sb.Append(TAB).Append("}\n\n");
|
||||
sb.Append(TAB).AppendFormat("auto *%s = CONTAINER_OF(", objName.c_str());
|
||||
sb.AppendFormat("deviceObject->service, struct Hdf%sHost, ioService);\n", baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat("if (%s != nullptr) {\n", objName.c_str());
|
||||
sb.Append(TAB).Append(TAB).AppendFormat("delete %s;\n", objName.c_str());
|
||||
sb.Append(TAB).Append("}\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CppServiceDriverCodeEmitter::EmitDriverEntryDefinition(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("struct HdfDriverEntry g_%sDriverEntry = {\n", StringHelper::StrToLower(baseName_).c_str());
|
||||
sb.Append(TAB).Append(".moduleVersion = 1,\n");
|
||||
sb.Append(TAB).AppendFormat(".moduleName = \"%s\",\n", Options::GetInstance().GetPackage().c_str());
|
||||
sb.Append(TAB).AppendFormat(".Bind = Hdf%sDriverBind,\n", baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat(".Init = Hdf%sDriverInit,\n", baseName_.c_str());
|
||||
sb.Append(TAB).AppendFormat(".Release = Hdf%sDriverRelease,\n", baseName_.c_str());
|
||||
sb.Append("};\n\n");
|
||||
EmitHeadExternC(sb);
|
||||
sb.AppendFormat("HDF_INIT(g_%sDriverEntry);\n", StringHelper::StrToLower(baseName_).c_str());
|
||||
EmitTailExternC(sb);
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
55
idl_tool_2/codegen/HDI/cpp/cpp_service_driver_code_emitter.h
Normal file
55
idl_tool_2/codegen/HDI/cpp/cpp_service_driver_code_emitter.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_CPP_SERVICE_DRIVER_CODE_EMITTER_H
|
||||
#define OHOS_IDL_CPP_SERVICE_DRIVER_CODE_EMITTER_H
|
||||
|
||||
#include "hdi_cpp_code_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
class CppServiceDriverCodeEmitter : public HDICppCodeEmitter {
|
||||
public:
|
||||
CppServiceDriverCodeEmitter() : HDICppCodeEmitter() {}
|
||||
|
||||
~CppServiceDriverCodeEmitter() override = default;
|
||||
|
||||
private:
|
||||
bool ResolveDirectory(const std::string &targetDirectory) override;
|
||||
|
||||
void EmitCode() override;
|
||||
|
||||
void EmitDriverSourceFile();
|
||||
|
||||
void EmitDriverInclusions(StringBuilder &sb);
|
||||
|
||||
void EmitDriverUsings(StringBuilder &sb);
|
||||
|
||||
void EmitDriverServiceDecl(StringBuilder &sb) const;
|
||||
|
||||
void EmitDriverDispatch(StringBuilder &sb) const;
|
||||
|
||||
void EmitDriverInit(StringBuilder &sb) const;
|
||||
|
||||
void EmitDriverBind(StringBuilder &sb) const;
|
||||
|
||||
void EmitDriverRelease(StringBuilder &sb) const;
|
||||
|
||||
void EmitDriverEntryDefinition(StringBuilder &sb) const;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_CPP_SERVICE_DRIVER_CODE_EMITTER_H
|
233
idl_tool_2/codegen/HDI/cpp/cpp_service_impl_code_emitter.cpp
Normal file
233
idl_tool_2/codegen/HDI/cpp/cpp_service_impl_code_emitter.cpp
Normal file
@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "cpp_service_impl_code_emitter.h"
|
||||
#include "util/file.h"
|
||||
#include "util/logger.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
bool CppServiceImplCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
|
||||
{
|
||||
if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
|
||||
directory_ = GetFileParentPath(targetDirectory);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!File::CreateParentDir(directory_)) {
|
||||
Logger::E("CppServiceImplCodeEmitter", "Create '%s' failed!", directory_.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CppServiceImplCodeEmitter::EmitCode()
|
||||
{
|
||||
switch (mode_) {
|
||||
case GenMode::PASSTHROUGH:
|
||||
case GenMode::IPC: {
|
||||
EmitImplHeaderFile();
|
||||
EmitImplSourceFile();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CppServiceImplCodeEmitter::EmitImplHeaderFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(implName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitHeadMacro(sb, implFullName_);
|
||||
sb.Append("\n");
|
||||
EmitServiceImplInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitServiceImplDecl(sb);
|
||||
sb.Append("\n");
|
||||
EmitTailMacro(sb, implFullName_);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CppServiceImplCodeEmitter::EmitServiceImplInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CppServiceImplCodeEmitter::EmitServiceImplDecl(StringBuilder &sb)
|
||||
{
|
||||
EmitBeginNamespace(sb);
|
||||
sb.AppendFormat("class %sService : public %s {\n", baseName_.c_str(),
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
sb.Append("public:\n");
|
||||
EmitServiceImplBody(sb, TAB);
|
||||
sb.Append("};\n");
|
||||
EmitEndNamespace(sb);
|
||||
}
|
||||
|
||||
void CppServiceImplCodeEmitter::EmitServiceImplBody(StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
(void)prefix;
|
||||
EmitServiceImplConstructor(sb, TAB);
|
||||
sb.Append("\n");
|
||||
EmitServiceImplMethodDecls(sb, TAB);
|
||||
}
|
||||
|
||||
void CppServiceImplCodeEmitter::EmitServiceImplConstructor(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("%s() = default;\n", implName_.c_str());
|
||||
sb.Append(prefix).AppendFormat("virtual ~%s() = default;\n", implName_.c_str());
|
||||
}
|
||||
|
||||
void CppServiceImplCodeEmitter::EmitServiceImplMethodDecls(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
AutoPtr<ASTInterfaceType> interface = interface_;
|
||||
while (interface != nullptr) {
|
||||
for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
EmitServiceImplMethodDecl(method, sb, prefix);
|
||||
sb.Append("\n");
|
||||
}
|
||||
interface = interface->GetExtendsInterface();
|
||||
}
|
||||
}
|
||||
|
||||
void CppServiceImplCodeEmitter::EmitServiceImplMethodDecl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
if (method->GetParameterNumber() == 0) {
|
||||
sb.Append(prefix).AppendFormat("int32_t %s() override;\n", method->GetName().c_str());
|
||||
} else {
|
||||
StringBuilder paramStr;
|
||||
paramStr.Append(prefix).AppendFormat("int32_t %s(", method->GetName().c_str());
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
EmitInterfaceMethodParameter(param, paramStr, "");
|
||||
if (i + 1 < method->GetParameterNumber()) {
|
||||
paramStr.Append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
paramStr.Append(") override;");
|
||||
|
||||
sb.Append(SpecificationParam(paramStr, prefix + TAB));
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void CppServiceImplCodeEmitter::EmitImplSourceFile()
|
||||
{
|
||||
std::string filePath = File::AdapterPath(
|
||||
StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(implName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitImplSourceInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitLogTagMacro(sb, FileName(implName_));
|
||||
sb.Append("\n");
|
||||
EmitBeginNamespace(sb);
|
||||
EmitServiceImplGetMethodImpl(sb, "");
|
||||
EmitServiceImplMethodImpls(sb, "");
|
||||
EmitEndNamespace(sb);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CppServiceImplCodeEmitter::EmitImplSourceInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(implName_));
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CppServiceImplCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
|
||||
{
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
|
||||
}
|
||||
|
||||
void CppServiceImplCodeEmitter::EmitServiceImplMethodImpls(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
AutoPtr<ASTInterfaceType> interface = interface_;
|
||||
while (interface != nullptr) {
|
||||
for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
EmitServiceImplMethodImpl(method, sb, prefix);
|
||||
sb.Append("\n");
|
||||
}
|
||||
interface = interface->GetExtendsInterface();
|
||||
}
|
||||
}
|
||||
|
||||
void CppServiceImplCodeEmitter::EmitServiceImplMethodImpl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
if (method->GetParameterNumber() == 0) {
|
||||
sb.Append(prefix).AppendFormat("int32_t %sService::%s()\n", baseName_.c_str(), method->GetName().c_str());
|
||||
} else {
|
||||
StringBuilder paramStr;
|
||||
paramStr.Append(prefix).AppendFormat("int32_t %sService::%s(", baseName_.c_str(), method->GetName().c_str());
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
EmitInterfaceMethodParameter(param, paramStr, "");
|
||||
if (i + 1 < method->GetParameterNumber()) {
|
||||
paramStr.Append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
paramStr.AppendFormat(")");
|
||||
|
||||
sb.Append(SpecificationParam(paramStr, prefix + TAB));
|
||||
sb.Append("\n");
|
||||
}
|
||||
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB).Append("return HDF_SUCCESS;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppServiceImplCodeEmitter::EmitServiceImplGetMethodImpl(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
if (!interface_->IsSerializable()) {
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"extern \"C\" %s *%sImplGetInstance(void)\n", interfaceName_.c_str(), baseName_.c_str());
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("return new (std::nothrow) %s();\n", implName_.c_str());
|
||||
sb.Append(prefix).Append("}\n\n");
|
||||
}
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
69
idl_tool_2/codegen/HDI/cpp/cpp_service_impl_code_emitter.h
Normal file
69
idl_tool_2/codegen/HDI/cpp/cpp_service_impl_code_emitter.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_CPP_SERVICE_IMPL_CODE_EMITTER_H
|
||||
#define OHOS_IDL_CPP_SERVICE_IMPL_CODE_EMITTER_H
|
||||
|
||||
#include "hdi_cpp_code_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
class CppServiceImplCodeEmitter : public HDICppCodeEmitter {
|
||||
public:
|
||||
CppServiceImplCodeEmitter() : HDICppCodeEmitter() {}
|
||||
|
||||
~CppServiceImplCodeEmitter() override = default;
|
||||
|
||||
private:
|
||||
bool ResolveDirectory(const std::string &targetDirectory) override;
|
||||
|
||||
void EmitCode() override;
|
||||
|
||||
void EmitImplHeaderFile();
|
||||
|
||||
void EmitServiceImplInclusions(StringBuilder &sb);
|
||||
|
||||
void EmitServiceImplDecl(StringBuilder &sb);
|
||||
|
||||
void EmitServiceImplBody(StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitServiceImplConstructor(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitServiceImplMethodDecls(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitServiceImplMethodDecl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitImplSourceFile();
|
||||
|
||||
void EmitImplSourceInclusions(StringBuilder &sb);
|
||||
|
||||
void GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const;
|
||||
|
||||
void EmitServiceImplMethodImpls(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitServiceImplMethodImpl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitExternalGetMethodImpl(StringBuilder &sb);
|
||||
|
||||
void EmitExternalReleaseMethodImpl(StringBuilder &sb);
|
||||
|
||||
void EmitServiceImplGetMethodImpl(StringBuilder &sb, const std::string &prefix) const;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_CPP_SERVICE_IMPL_CODE_EMITTER_H
|
597
idl_tool_2/codegen/HDI/cpp/cpp_service_stub_code_emitter.cpp
Normal file
597
idl_tool_2/codegen/HDI/cpp/cpp_service_stub_code_emitter.cpp
Normal file
@ -0,0 +1,597 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "cpp_service_stub_code_emitter.h"
|
||||
#include "util/file.h"
|
||||
#include "util/logger.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
bool CppServiceStubCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
|
||||
{
|
||||
if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
|
||||
directory_ = GetFileParentPath(targetDirectory);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!File::CreateParentDir(directory_)) {
|
||||
Logger::E("CppServiceStubCodeEmitter", "Create '%s' failed!", directory_.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitCode()
|
||||
{
|
||||
if (mode_ == GenMode::IPC) {
|
||||
EmitStubHeaderFile();
|
||||
EmitStubSourceFile();
|
||||
}
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubHeaderFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(stubName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitHeadMacro(sb, stubFullName_);
|
||||
sb.Append("\n");
|
||||
EmitStubHeaderInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitStubDecl(sb);
|
||||
sb.Append("\n");
|
||||
EmitTailMacro(sb, stubFullName_);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubHeaderInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
|
||||
headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
|
||||
if (interface_->GetExtendsInterface() != nullptr) {
|
||||
headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE,
|
||||
EmitHeaderNameByInterface(interface_->GetExtendsInterface(), stubName_));
|
||||
}
|
||||
GetHeaderOtherLibInclusions(headerFiles);
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
|
||||
{
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_parcel");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_option");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "ipc_object_stub");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "object_collector");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "refbase");
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubDecl(StringBuilder &sb)
|
||||
{
|
||||
EmitBeginNamespace(sb);
|
||||
sb.Append("\n");
|
||||
EmitStubUsingNamespace(sb);
|
||||
sb.AppendFormat("class %s : public IPCObjectStub {\n", stubName_.c_str());
|
||||
EmitStubBody(sb, TAB);
|
||||
sb.Append("};\n");
|
||||
EmitEndNamespace(sb);
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubUsingNamespace(StringBuilder &sb) const
|
||||
{
|
||||
sb.Append("using namespace OHOS;\n");
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubBody(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append("public:\n");
|
||||
EmitStubConstructorDecl(sb, prefix);
|
||||
sb.Append("\n");
|
||||
EmitStubOnRequestDecl(sb, prefix);
|
||||
sb.Append("\n");
|
||||
EmitStubMethodDecls(sb, prefix);
|
||||
sb.Append("\n");
|
||||
EmitStubPrivateData(sb, prefix);
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubConstructorDecl(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("explicit %s(const sptr<%s> &impl);\n", stubName_.c_str(), interfaceName_.c_str());
|
||||
sb.Append(prefix).AppendFormat("virtual ~%s();\n", stubName_.c_str());
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubOnRequestDecl(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).Append("int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, ");
|
||||
sb.Append("MessageOption &option) override;\n");
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubMethodDecls(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
EmitStubStaticMethodDecl(method, sb, prefix);
|
||||
sb.Append("\n");
|
||||
}
|
||||
if (interface_->GetExtendsInterface() == nullptr) {
|
||||
EmitStubStaticMethodDecl(interface_->GetVersionMethod(), sb, prefix);
|
||||
sb.Append("\n");
|
||||
}
|
||||
|
||||
sb.Append("private:\n");
|
||||
AutoPtr<ASTInterfaceType> interface = interface_;
|
||||
while (interface != nullptr) {
|
||||
for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
EmitStubMethodDecl(method, sb, prefix);
|
||||
sb.Append("\n");
|
||||
}
|
||||
interface = interface->GetExtendsInterface();
|
||||
}
|
||||
EmitStubMethodDecl(interface_->GetVersionMethod(), sb, prefix);
|
||||
sb.Append("\n");
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubMethodDecl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("int32_t %s%s%s(MessageParcel& %s, MessageParcel& %s, MessageOption& %s);\n",
|
||||
stubName_.c_str(), method->GetName().c_str(), method->GetMethodIdentifier().c_str(),
|
||||
HdiTypeEmitter::dataParcelName_.c_str(), HdiTypeEmitter::replyParcelName_.c_str(), optionName_.c_str());
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubStaticMethodDecl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"static int32_t %s%s%s_(MessageParcel& %s, MessageParcel& %s, MessageOption& %s, sptr<%s> impl);\n",
|
||||
stubName_.c_str(), method->GetName().c_str(), method->GetMethodIdentifier().c_str(),
|
||||
HdiTypeEmitter::dataParcelName_.c_str(), HdiTypeEmitter::replyParcelName_.c_str(),
|
||||
optionName_.c_str(), EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubPrivateData(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("static inline ObjectDelegator<%s, %s> objDelegator_;\n",
|
||||
EmitDefinitionByInterface(interface_, stubName_).c_str(),
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
sb.Append(prefix).AppendFormat("sptr<%s> impl_;\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubSourceFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(stubName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitStubSourceInclusions(sb);
|
||||
sb.Append("\n");
|
||||
EmitLogTagMacro(sb, FileName(stubName_));
|
||||
sb.Append("\n");
|
||||
EmitBeginNamespace(sb);
|
||||
EmitUtilMethods(sb, true);
|
||||
sb.Append("\n");
|
||||
EmitUtilMethods(sb, false);
|
||||
sb.Append("\n");
|
||||
EmitInterfaceGetMethodImpl(sb, "");
|
||||
sb.Append("\n");
|
||||
EmitStubConstructorImpl(sb, "");
|
||||
sb.Append("\n");
|
||||
EmitStubOnRequestMethodImpl(sb, "");
|
||||
sb.Append("\n");
|
||||
EmitStubMethodImpls(sb, "");
|
||||
EmitEndNamespace(sb);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubSourceInclusions(StringBuilder &sb)
|
||||
{
|
||||
HeaderFile::HeaderFileSet headerFiles;
|
||||
headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(stubName_));
|
||||
GetSourceOtherLibInclusions(headerFiles);
|
||||
GetSourceOtherFileInclusions(headerFiles);
|
||||
|
||||
for (const auto &file : headerFiles) {
|
||||
sb.AppendFormat("%s\n", file.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
|
||||
{
|
||||
if (!interface_->IsSerializable()) {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "string_ex");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
|
||||
} else {
|
||||
const AST::TypeStringMap &types = ast_->GetTypes();
|
||||
for (const auto &pair : types) {
|
||||
AutoPtr<ASTType> type = pair.second;
|
||||
if (type->GetTypeKind() == TypeKind::TYPE_UNION) {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
|
||||
AutoPtr<ASTType> paramType = param->GetType();
|
||||
if ((param->GetAttribute() == ASTParamAttr::PARAM_IN) &&
|
||||
(param->GetType()->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iproxy_broker");
|
||||
}
|
||||
|
||||
if ((param->GetAttribute() == ASTParamAttr::PARAM_OUT) &&
|
||||
(param->GetType()->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "object_collector");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::GetSourceOtherFileInclusions(HeaderFile::HeaderFileSet &headerFiles) const
|
||||
{
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
|
||||
AutoPtr<ASTType> paramType = param->GetType();
|
||||
if ((param->GetAttribute() == ASTParamAttr::PARAM_IN) &&
|
||||
(param->GetType()->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
|
||||
AutoPtr<ASTInterfaceType> type = dynamic_cast<ASTInterfaceType *>(paramType.Get());
|
||||
std::string FileName = InterfaceToFilePath(paramType->ToString());
|
||||
headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, FileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitInterfaceGetMethodImpl(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
if (!interface_->IsSerializable()) {
|
||||
EmitGetMethodImpl(sb, prefix);
|
||||
sb.Append(prefix).Append("\n");
|
||||
EmitGetInstanceMethodImpl(sb, prefix);
|
||||
sb.Append(prefix).Append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitGetMethodImpl(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(bool isStub)\n",
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("return %s::Get(\"%s\", isStub);\n",
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str(), FileName(implName_).c_str());
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitGetInstanceMethodImpl(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(const std::string& serviceName, bool isStub)\n",
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
sb.Append(prefix).Append("{\n");
|
||||
|
||||
sb.Append(prefix + TAB).Append("if (!isStub) {\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n");
|
||||
|
||||
sb.Append(prefix + TAB).AppendFormat("std::string desc = Str16ToStr8(%s::GetDescriptor());\n",
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
sb.Append(prefix + TAB).Append("void *impl = LoadHdiImpl(desc.c_str(), ");
|
||||
sb.AppendFormat("serviceName == \"%s\" ? \"service\" : serviceName.c_str());\n", FileName(implName_).c_str());
|
||||
sb.Append(prefix + TAB).Append("if (impl == nullptr) {\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"failed to load hdi impl %{public}s\", desc.c_str());\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("return reinterpret_cast<%s *>(impl);\n",
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubConstructorImpl(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("%s::%s(const sptr<%s> &impl)\n",
|
||||
EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str(),
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat(": IPCObjectStub(%s::GetDescriptor()), impl_(impl)\n",
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix).Append("}\n\n");
|
||||
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"%s::~%s()\n", EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str());
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB).Append("ObjectCollector::GetInstance().RemoveObject(impl_);\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubOnRequestMethodImpl(StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"int32_t %s::OnRemoteRequest(uint32_t code, ", EmitDefinitionByInterface(interface_, stubName_).c_str());
|
||||
sb.Append("MessageParcel& data, MessageParcel& reply, MessageOption& option)\n");
|
||||
sb.Append(prefix).Append("{\n");
|
||||
|
||||
sb.Append(prefix + TAB).Append("switch (code) {\n");
|
||||
AutoPtr<ASTMethod> getVerMethod = interface_->GetVersionMethod();
|
||||
sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(getVerMethod).c_str());
|
||||
sb.Append(prefix + TAB + TAB + TAB)
|
||||
.AppendFormat("return %sStub%s%s(data, reply, option);\n",
|
||||
baseName_.c_str(), getVerMethod->GetName().c_str(), getVerMethod->GetMethodIdentifier().c_str());
|
||||
AutoPtr<ASTInterfaceType> interface = interface_;
|
||||
while (interface != nullptr) {
|
||||
for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(method).c_str());
|
||||
sb.Append(prefix + TAB + TAB + TAB)
|
||||
.AppendFormat("return %sStub%s%s(data, reply, option);\n",
|
||||
baseName_.c_str(), method->GetName().c_str(), method->GetMethodIdentifier().c_str());
|
||||
}
|
||||
interface = interface->GetExtendsInterface();
|
||||
}
|
||||
|
||||
sb.Append(prefix + TAB + TAB).Append("default: {\n");
|
||||
sb.Append(prefix + TAB + TAB + TAB)
|
||||
.Append("HDF_LOGE(\"%{public}s: cmd %{public}d is not supported\", __func__, code);\n");
|
||||
sb.Append(prefix + TAB + TAB + TAB).Append("return IPCObjectStub::OnRemoteRequest(code, data, reply, option);\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("}\n");
|
||||
sb.Append(prefix + TAB).Append("}\n");
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubMethodImpls(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
AutoPtr<ASTInterfaceType> interface = interface_;
|
||||
AutoPtr<ASTInterfaceType> mataInterface = interface_;
|
||||
while (interface != nullptr) {
|
||||
for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
EmitStubMethodImpl(interface, method, sb, prefix);
|
||||
sb.Append("\n");
|
||||
}
|
||||
interface = interface->GetExtendsInterface();
|
||||
if (interface != nullptr) {
|
||||
mataInterface = interface;
|
||||
}
|
||||
}
|
||||
AutoPtr<ASTMethod> verMethod = interface_->GetVersionMethod();
|
||||
EmitStubMethodImpl(mataInterface, verMethod, sb, prefix);
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
sb.Append("\n");
|
||||
EmitStubStaticMethodImpl(method, sb, prefix);
|
||||
}
|
||||
if (interface_->GetExtendsInterface() == nullptr) {
|
||||
sb.Append("\n");
|
||||
EmitStubStaticMethodImpl(verMethod, sb, prefix);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubMethodImpl(AutoPtr<ASTInterfaceType> interface,
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("int32_t %s::%s%s%s(MessageParcel& %s, MessageParcel& %s, MessageOption& %s)\n",
|
||||
EmitDefinitionByInterface(interface_, stubName_).c_str(),
|
||||
stubName_.c_str(), method->GetName().c_str(), method->GetMethodIdentifier().c_str(),
|
||||
HdiTypeEmitter::dataParcelName_.c_str(), HdiTypeEmitter::replyParcelName_.c_str(), optionName_.c_str());
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("return %s::%s%s%s_(%s, %s, %s, impl_);\n",
|
||||
EmitDefinitionByInterface(interface, stubName_).c_str(),
|
||||
stubName_.c_str(), method->GetName().c_str(), method->GetMethodIdentifier().c_str(),
|
||||
HdiTypeEmitter::dataParcelName_.c_str(), HdiTypeEmitter::replyParcelName_.c_str(),
|
||||
optionName_.c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubStaticMethodImpl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"int32_t %s::%s%s%s_(MessageParcel& %s, MessageParcel& %s, MessageOption& %s, sptr<%s> impl)\n",
|
||||
EmitDefinitionByInterface(interface_, stubName_).c_str(),
|
||||
stubName_.c_str(), method->GetName().c_str(), method->GetMethodIdentifier().c_str(),
|
||||
HdiTypeEmitter::dataParcelName_.c_str(), HdiTypeEmitter::replyParcelName_.c_str(), optionName_.c_str(),
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
sb.Append(prefix).Append("{\n");
|
||||
|
||||
// read interface token and check it
|
||||
EmitStubReadInterfaceToken(HdiTypeEmitter::dataParcelName_, sb, prefix + TAB);
|
||||
sb.Append("\n");
|
||||
|
||||
EmitStubReadMemFlag(method, HdiTypeEmitter::dataParcelName_, sb, prefix + TAB);
|
||||
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
if (param->GetAttribute() == ASTParamAttr::PARAM_IN) {
|
||||
EmitReadMethodParameter(param, TypeMode::PARAM_IN, sb, prefix + TAB);
|
||||
sb.Append("\n");
|
||||
} else {
|
||||
EmitLocalVariable(param, HdiTypeEmitter::dataParcelName_, sb, prefix + TAB);
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
EmitStubCallMethod(method, sb, prefix + TAB);
|
||||
sb.Append("\n");
|
||||
|
||||
if (!method->IsOneWay()) {
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
if (param->GetAttribute() == ASTParamAttr::PARAM_OUT) {
|
||||
EmitWriteMethodParameter(param, HdiTypeEmitter::replyParcelName_, sb, prefix + TAB);
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sb.Append(prefix + TAB).AppendFormat("return %s;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append("}\n");
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubCallMethod(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).Append("if (impl == nullptr) {\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: impl is nullptr!\", __func__);\n");
|
||||
sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
|
||||
sb.Append(prefix).Append("}\n\n");
|
||||
|
||||
sb.Append(prefix).AppendFormat("int32_t %s = impl->%s(", HdiTypeEmitter::errorCodeName_.c_str(),
|
||||
method->GetName().c_str());
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
sb.Append(param->GetName());
|
||||
if (i + 1 < method->GetParameterNumber()) {
|
||||
sb.Append(", ");
|
||||
}
|
||||
}
|
||||
sb.Append(");\n");
|
||||
|
||||
sb.Append(prefix).AppendFormat("if (%s != HDF_SUCCESS) {\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB)
|
||||
.AppendFormat("HDF_LOGE(\"%%{public}s failed, error code is %%{public}d\", __func__, %s);\n",
|
||||
HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("return %s;\n", HdiTypeEmitter::errorCodeName_.c_str());
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubReadInterfaceToken(
|
||||
const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("if (%s.ReadInterfaceToken() != %s::GetDescriptor()) {\n", parcelName.c_str(),
|
||||
EmitDefinitionByInterface(interface_, interfaceName_).c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: interface token check failed!\", __func__);\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitStubReadMemFlag(const AutoPtr<ASTMethod> &method,
|
||||
const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
if (NeedFlag(method)) {
|
||||
sb.Append(prefix).AppendFormat("bool %s = false;\n", flagOfSetMemName_.c_str());
|
||||
sb.Append(prefix).AppendFormat("if (!%s.ReadBool(%s)) {\n", parcelName.c_str(), flagOfSetMemName_.c_str());
|
||||
sb.Append(prefix + TAB)
|
||||
.AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", flagOfSetMemName_.c_str());
|
||||
sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitLocalVariable(const AutoPtr<ASTParameter> ¶m,
|
||||
const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
EmitCppLocalVar(param, sb, prefix);
|
||||
AutoPtr<ASTType> type = param->GetType();
|
||||
if (!type->IsStringType() && !type->IsArrayType() && !type->IsListType()) {
|
||||
return;
|
||||
}
|
||||
|
||||
sb.Append(prefix).AppendFormat("if (%s) {\n", flagOfSetMemName_.c_str());
|
||||
std::string capacityName = "capacity";
|
||||
sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", capacityName.c_str());
|
||||
sb.Append(prefix + TAB).AppendFormat("if (!%s.ReadUint32(%s)) {\n", parcelName.c_str(), capacityName.c_str());
|
||||
sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n",
|
||||
capacityName.c_str());
|
||||
sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
|
||||
sb.Append(prefix + TAB).Append("}\n");
|
||||
|
||||
if (type->IsStringType()) {
|
||||
sb.Append(prefix + TAB).AppendFormat("%s(%s, >, %s / sizeof(char), HDF_ERR_INVALID_PARAM);\n",
|
||||
CHECK_VALUE_RETURN_MACRO, capacityName.c_str(), MAX_BUFF_SIZE_MACRO);
|
||||
} else {
|
||||
AutoPtr<ASTArrayType> arrayType = dynamic_cast<ASTArrayType *>(type.Get());
|
||||
sb.Append(prefix + TAB).AppendFormat("%s(%s, >, %s / sizeof(%s), HDF_ERR_INVALID_PARAM);\n",
|
||||
CHECK_VALUE_RETURN_MACRO, capacityName.c_str(), MAX_BUFF_SIZE_MACRO,
|
||||
GetTypeEmitter(arrayType->GetElementType())->EmitCppType().c_str());
|
||||
}
|
||||
sb.Append(prefix + TAB).AppendFormat("%s.reserve(%s);\n", param->GetName().c_str(), capacityName.c_str());
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitCppLocalVar(const AutoPtr<ASTParameter> ¶m,
|
||||
StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
AutoPtr<ASTType> type = param->GetType();
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
|
||||
sb.Append(prefix).AppendFormat("%s %s", typeEmitter->EmitCppType(TypeMode::LOCAL_VAR).c_str(),
|
||||
param->GetName().c_str());
|
||||
switch (type->GetTypeKind()) {
|
||||
case TypeKind::TYPE_BOOLEAN:
|
||||
sb.Append(" = false");
|
||||
break;
|
||||
case TypeKind::TYPE_BYTE:
|
||||
case TypeKind::TYPE_SHORT:
|
||||
case TypeKind::TYPE_INT:
|
||||
case TypeKind::TYPE_LONG:
|
||||
case TypeKind::TYPE_UCHAR:
|
||||
case TypeKind::TYPE_USHORT:
|
||||
case TypeKind::TYPE_UINT:
|
||||
case TypeKind::TYPE_ULONG:
|
||||
case TypeKind::TYPE_FLOAT:
|
||||
case TypeKind::TYPE_DOUBLE:
|
||||
sb.Append(" = 0");
|
||||
break;
|
||||
case TypeKind::TYPE_FILEDESCRIPTOR:
|
||||
sb.Append(" = -1");
|
||||
break;
|
||||
case TypeKind::TYPE_SEQUENCEABLE:
|
||||
sb.Append(" = nullptr");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sb.Append(";\n");
|
||||
}
|
||||
|
||||
void CppServiceStubCodeEmitter::EmitUtilMethods(StringBuilder &sb, bool isDecl)
|
||||
{
|
||||
UtilMethodMap methods;
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
|
||||
AutoPtr<ASTType> paramType = param->GetType();
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
|
||||
if (param->GetAttribute() == ASTParamAttr::PARAM_IN) {
|
||||
typeEmitter->EmitCppReadMethods(methods, "", "", isDecl);
|
||||
} else {
|
||||
typeEmitter->EmitCppWriteMethods(methods, "", "", isDecl);
|
||||
}
|
||||
}
|
||||
}
|
||||
EmitUtilMethodMap(sb, methods);
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
102
idl_tool_2/codegen/HDI/cpp/cpp_service_stub_code_emitter.h
Normal file
102
idl_tool_2/codegen/HDI/cpp/cpp_service_stub_code_emitter.h
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_CPP_SERVICE_STUB_CODE_EMITTER_H
|
||||
#define OHOS_IDL_CPP_SERVICE_STUB_CODE_EMITTER_H
|
||||
|
||||
#include "hdi_cpp_code_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
class CppServiceStubCodeEmitter : public HDICppCodeEmitter {
|
||||
public:
|
||||
CppServiceStubCodeEmitter() : HDICppCodeEmitter() {}
|
||||
|
||||
~CppServiceStubCodeEmitter() override = default;
|
||||
|
||||
private:
|
||||
bool ResolveDirectory(const std::string &targetDirectory) override;
|
||||
|
||||
void EmitCode() override;
|
||||
|
||||
// ISample.idl -> sample_service_stub.h
|
||||
void EmitStubHeaderFile();
|
||||
|
||||
void EmitStubHeaderInclusions(StringBuilder &sb);
|
||||
|
||||
void GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const;
|
||||
|
||||
void EmitStubUsingNamespace(StringBuilder &sb) const;
|
||||
|
||||
void EmitStubDecl(StringBuilder &sb);
|
||||
|
||||
void EmitStubBody(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitStubConstructorDecl(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitStubOnRequestDecl(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitStubMethodDecls(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitStubMethodDecl(const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitStubPrivateData(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
// ISample.idl -> sample_service_stub.cpp
|
||||
void EmitStubSourceFile();
|
||||
|
||||
void EmitStubSourceInclusions(StringBuilder &sb);
|
||||
|
||||
void GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const;
|
||||
|
||||
void GetSourceOtherFileInclusions(HeaderFile::HeaderFileSet &headerFiles) const;
|
||||
|
||||
void EmitInterfaceGetMethodImpl(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitGetMethodImpl(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitGetInstanceMethodImpl(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitStubConstructorImpl(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitStubOnRequestMethodImpl(StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitStubMethodImpls(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitStubMethodImpl(AutoPtr<ASTInterfaceType> interface, const AutoPtr<ASTMethod> &method, StringBuilder &sb,
|
||||
const std::string &prefix) const;
|
||||
|
||||
void EmitStubStaticMethodImpl(const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitStubCallMethod(const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitStubReadInterfaceToken(const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitStubReadMemFlag(const AutoPtr<ASTMethod> &method, const std::string &parcelName, StringBuilder &sb,
|
||||
const std::string &prefix) const;
|
||||
|
||||
void EmitLocalVariable(const AutoPtr<ASTParameter> ¶m, const std::string &parcelName, StringBuilder &sb,
|
||||
const std::string &prefix) const;
|
||||
|
||||
void EmitUtilMethods(StringBuilder &sb, bool isDecl) override;
|
||||
|
||||
void EmitStubStaticMethodDecl(const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitCppLocalVar(const AutoPtr<ASTParameter> ¶m, StringBuilder &sb, const std::string &prefix) const;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_CPP_SERVICE_STUB_CODE_EMITTER_H
|
260
idl_tool_2/codegen/HDI/cpp/hdi_cpp_code_emitter.cpp
Normal file
260
idl_tool_2/codegen/HDI/cpp/hdi_cpp_code_emitter.cpp
Normal file
@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "hdi_cpp_code_emitter.h"
|
||||
|
||||
#include <regex>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "util/options.h"
|
||||
|
||||
#include "util/logger.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
void HDICppCodeEmitter::GetImportInclusions(HeaderFile::HeaderFileSet &headerFiles)
|
||||
{
|
||||
for (const auto &importPair : ast_->GetImports()) {
|
||||
AutoPtr<AST> importAst = importPair.second;
|
||||
std::string fileName = (importAst->GetASTFileType() == ASTFileType::AST_SEQUENCEABLE) ?
|
||||
PackageToFilePath(importAst->GetName()) :
|
||||
PackageToFilePath(importAst->GetFullName());
|
||||
headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, fileName);
|
||||
}
|
||||
}
|
||||
|
||||
void HDICppCodeEmitter::EmitInterfaceMethodParameter(
|
||||
const AutoPtr<ASTParameter> ¶m, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
std::string name = param->GetName();
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
|
||||
if (param->GetAttribute() == ASTParamAttr::PARAM_IN) {
|
||||
sb.Append(prefix).AppendFormat("%s %s", typeEmitter->EmitCppType(TypeMode::PARAM_IN).c_str(), name.c_str());
|
||||
} else {
|
||||
sb.Append(prefix).AppendFormat("%s %s", typeEmitter->EmitCppType(TypeMode::PARAM_OUT).c_str(), name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
bool HDICppCodeEmitter::IsVersion(const std::string &name) const
|
||||
{
|
||||
std::regex rVer("[V|v][0-9]+_[0-9]+");
|
||||
return std::regex_match(name.c_str(), rVer);
|
||||
}
|
||||
|
||||
std::vector<std::string> HDICppCodeEmitter::EmitCppNameSpaceVec(const std::string &namespaceStr) const
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
std::vector<std::string> namespaceVec = StringHelper::Split(namespaceStr, ".");
|
||||
bool findVersion = false;
|
||||
|
||||
std::string rootPackage = Options::GetInstance().GetRootPackage(namespaceStr);
|
||||
size_t rootPackageNum = StringHelper::Split(rootPackage, ".").size();
|
||||
|
||||
for (size_t i = 0; i < namespaceVec.size(); i++) {
|
||||
std::string name;
|
||||
if (i < rootPackageNum) {
|
||||
name = StringHelper::StrToUpper(namespaceVec[i]);
|
||||
} else if (!findVersion && IsVersion(namespaceVec[i])) {
|
||||
name = StringHelper::Replace(namespaceVec[i], 'v', 'V');
|
||||
findVersion = true;
|
||||
} else {
|
||||
if (findVersion) {
|
||||
name = namespaceVec[i];
|
||||
} else {
|
||||
name = PascalName(namespaceVec[i]);
|
||||
}
|
||||
}
|
||||
|
||||
result.emplace_back(name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string HDICppCodeEmitter::EmitPackageToNameSpace(const std::string &packageName) const
|
||||
{
|
||||
if (packageName.empty()) {
|
||||
return packageName;
|
||||
}
|
||||
|
||||
StringBuilder nameSpaceStr;
|
||||
std::vector<std::string> namespaceVec = EmitCppNameSpaceVec(packageName);
|
||||
for (auto nameIter = namespaceVec.begin(); nameIter != namespaceVec.end(); nameIter++) {
|
||||
nameSpaceStr.Append(*nameIter);
|
||||
if (nameIter != namespaceVec.end() - 1) {
|
||||
nameSpaceStr.Append("::");
|
||||
}
|
||||
}
|
||||
|
||||
return nameSpaceStr.ToString();
|
||||
}
|
||||
|
||||
void HDICppCodeEmitter::GetStdlibInclusions(HeaderFile::HeaderFileSet &headerFiles)
|
||||
{
|
||||
const AST::TypeStringMap &types = ast_->GetTypes();
|
||||
for (const auto &pair : types) {
|
||||
AutoPtr<ASTType> type = pair.second;
|
||||
switch (type->GetTypeKind()) {
|
||||
case TypeKind::TYPE_STRING: {
|
||||
headerFiles.emplace(HeaderFileType::CPP_STD_HEADER_FILE, "string");
|
||||
break;
|
||||
}
|
||||
case TypeKind::TYPE_ARRAY:
|
||||
case TypeKind::TYPE_LIST: {
|
||||
headerFiles.emplace(HeaderFileType::CPP_STD_HEADER_FILE, "vector");
|
||||
break;
|
||||
}
|
||||
case TypeKind::TYPE_MAP: {
|
||||
headerFiles.emplace(HeaderFileType::CPP_STD_HEADER_FILE, "map");
|
||||
break;
|
||||
}
|
||||
case TypeKind::TYPE_SMQ: {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "base/hdi_smq");
|
||||
break;
|
||||
}
|
||||
case TypeKind::TYPE_ASHMEM: {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "ashmem");
|
||||
break;
|
||||
}
|
||||
case TypeKind::TYPE_NATIVE_BUFFER: {
|
||||
headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "base/native_buffer");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HDICppCodeEmitter::EmitBeginNamespace(StringBuilder &sb)
|
||||
{
|
||||
std::vector<std::string> cppNamespaceVec = EmitCppNameSpaceVec(interface_->GetNamespace()->ToString());
|
||||
for (const auto &nspace : cppNamespaceVec) {
|
||||
sb.AppendFormat("namespace %s {\n", nspace.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void HDICppCodeEmitter::EmitEndNamespace(StringBuilder &sb)
|
||||
{
|
||||
std::vector<std::string> cppNamespaceVec = EmitCppNameSpaceVec(interface_->GetNamespace()->ToString());
|
||||
|
||||
for (std::vector<std::string>::const_reverse_iterator nspaceIter = cppNamespaceVec.rbegin();
|
||||
nspaceIter != cppNamespaceVec.rend(); ++nspaceIter) {
|
||||
sb.AppendFormat("} // %s\n", nspaceIter->c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void HDICppCodeEmitter::EmitUsingNamespace(StringBuilder &sb)
|
||||
{
|
||||
sb.Append("using namespace OHOS;\n");
|
||||
sb.Append("using namespace OHOS::HDI;\n");
|
||||
EmitImportUsingNamespace(sb);
|
||||
}
|
||||
|
||||
std::string HDICppCodeEmitter::EmitNamespace(const std::string &packageName) const
|
||||
{
|
||||
if (packageName.empty()) {
|
||||
return packageName;
|
||||
}
|
||||
|
||||
size_t index = packageName.rfind('.');
|
||||
return index != std::string::npos ? StringHelper::SubStr(packageName, 0, index) : packageName;
|
||||
}
|
||||
|
||||
void HDICppCodeEmitter::EmitImportUsingNamespace(StringBuilder &sb)
|
||||
{
|
||||
using StringSet = std::unordered_set<std::string>;
|
||||
StringSet namespaceSet;
|
||||
std::string selfNameSpace = EmitPackageToNameSpace(EmitNamespace(ast_->GetFullName()));
|
||||
|
||||
for (const auto &importPair : ast_->GetImports()) {
|
||||
AutoPtr<AST> import = importPair.second;
|
||||
std::string nameSpace = EmitPackageToNameSpace(EmitNamespace(import->GetFullName()));
|
||||
if (nameSpace == selfNameSpace) {
|
||||
continue;
|
||||
}
|
||||
namespaceSet.emplace(nameSpace);
|
||||
}
|
||||
|
||||
const AST::TypeStringMap &types = ast_->GetTypes();
|
||||
for (const auto &pair : types) {
|
||||
AutoPtr<ASTType> type = pair.second;
|
||||
if (type->GetTypeKind() == TypeKind::TYPE_SMQ ||
|
||||
type->GetTypeKind() == TypeKind::TYPE_NATIVE_BUFFER) {
|
||||
namespaceSet.emplace("OHOS::HDI::Base");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &nspace : namespaceSet) {
|
||||
sb.Append("using namespace ").AppendFormat("%s;\n", nspace.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void HDICppCodeEmitter::EmitWriteMethodParameter(const AutoPtr<ASTParameter> ¶m,
|
||||
const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
|
||||
typeEmitter->EmitCppWriteVar(parcelName, param->GetName(), sb, prefix);
|
||||
}
|
||||
|
||||
void HDICppCodeEmitter::EmitReadMethodParameter(const AutoPtr<ASTParameter> ¶m, TypeMode mode,
|
||||
StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
|
||||
typeEmitter->EmitCppReadVar(param->GetName(), sb, prefix, mode);
|
||||
}
|
||||
|
||||
std::string HDICppCodeEmitter::SpecificationParam(StringBuilder ¶mSb, const std::string &prefix) const
|
||||
{
|
||||
size_t maxLineLen = 120;
|
||||
size_t replaceLen = 2;
|
||||
std::string paramStr = paramSb.ToString();
|
||||
size_t preIndex = 0;
|
||||
size_t curIndex = 0;
|
||||
|
||||
std::string insertStr = StringHelper::Format("\n%s", prefix.c_str());
|
||||
for (; curIndex < paramStr.size(); curIndex++) {
|
||||
if (curIndex == maxLineLen && preIndex > 0) {
|
||||
StringHelper::Replace(paramStr, preIndex, replaceLen, ",");
|
||||
paramStr.insert(preIndex + 1, insertStr);
|
||||
} else {
|
||||
if (paramStr[curIndex] == ',') {
|
||||
preIndex = curIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
return paramStr;
|
||||
}
|
||||
|
||||
std::string HDICppCodeEmitter::EmitHeaderNameByInterface(AutoPtr<ASTInterfaceType> interface, const std::string &name)
|
||||
{
|
||||
return StringHelper::Format(
|
||||
"v%u_%u/%s", interface->GetMajorVersion(), interface->GetMinorVersion(), FileName(name).c_str());
|
||||
}
|
||||
|
||||
std::string HDICppCodeEmitter::EmitDefinitionByInterface(
|
||||
AutoPtr<ASTInterfaceType> interface, const std::string &name) const
|
||||
{
|
||||
StringBuilder sb;
|
||||
std::vector<std::string> cppNamespaceVec = EmitCppNameSpaceVec(interface->GetNamespace()->ToString());
|
||||
for (const auto &nspace : cppNamespaceVec) {
|
||||
sb.AppendFormat("%s", nspace.c_str());
|
||||
sb.Append("::");
|
||||
}
|
||||
sb.Append(name.c_str());
|
||||
return sb.ToString();
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
69
idl_tool_2/codegen/HDI/cpp/hdi_cpp_code_emitter.h
Normal file
69
idl_tool_2/codegen/HDI/cpp/hdi_cpp_code_emitter.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_HDI_CPP_CODE_EMITTER_H
|
||||
#define OHOS_IDL_HDI_CPP_CODE_EMITTER_H
|
||||
|
||||
#include "codegen/HDI/hdi_code_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
class HDICppCodeEmitter : public HDICodeEmitter {
|
||||
public:
|
||||
~HDICppCodeEmitter() override = default;
|
||||
|
||||
bool OutPut(const AutoPtr<AST> &ast, const std::string &targetDirectory);
|
||||
|
||||
protected:
|
||||
|
||||
void GetImportInclusions(HeaderFile::HeaderFileSet &headerFiles);
|
||||
|
||||
void EmitInterfaceMethodParameter(
|
||||
const AutoPtr<ASTParameter> ¶m, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
bool IsVersion(const std::string &name) const;
|
||||
|
||||
void GetStdlibInclusions(HeaderFile::HeaderFileSet &headerFiles);
|
||||
|
||||
std::vector<std::string> EmitCppNameSpaceVec(const std::string &namespaceStr) const;
|
||||
|
||||
std::string EmitPackageToNameSpace(const std::string &packageName) const;
|
||||
|
||||
virtual void EmitBeginNamespace(StringBuilder &sb);
|
||||
|
||||
virtual void EmitEndNamespace(StringBuilder &sb);
|
||||
|
||||
virtual void EmitUsingNamespace(StringBuilder &sb);
|
||||
|
||||
std::string EmitNamespace(const std::string &packageName) const;
|
||||
|
||||
void EmitImportUsingNamespace(StringBuilder &sb);
|
||||
|
||||
void EmitWriteMethodParameter(const AutoPtr<ASTParameter> ¶m, const std::string &parcelName, StringBuilder &sb,
|
||||
const std::string &prefix) const;
|
||||
|
||||
void EmitReadMethodParameter(const AutoPtr<ASTParameter> ¶m, TypeMode mode, StringBuilder &sb,
|
||||
const std::string &prefix) const;
|
||||
|
||||
std::string SpecificationParam(StringBuilder ¶mSb, const std::string &prefix) const;
|
||||
|
||||
std::string EmitHeaderNameByInterface(AutoPtr<ASTInterfaceType> interface, const std::string &name);
|
||||
|
||||
std::string EmitDefinitionByInterface(AutoPtr<ASTInterfaceType> interface, const std::string &name) const;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_CPP_CODE_EMITTER_H
|
346
idl_tool_2/codegen/HDI/hdi_code_emitter.cpp
Normal file
346
idl_tool_2/codegen/HDI/hdi_code_emitter.cpp
Normal file
@ -0,0 +1,346 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "hdi_code_emitter.h"
|
||||
#include "type/hdi_boolean_type_emitter.h"
|
||||
#include "type/hdi_byte_type_emitter.h"
|
||||
#include "type/hdi_short_type_emitter.h"
|
||||
#include "type/hdi_int_type_emitter.h"
|
||||
#include "type/hdi_long_type_emitter.h"
|
||||
#include "type/hdi_float_type_emitter.h"
|
||||
#include "type/hdi_double_type_emitter.h"
|
||||
#include "type/hdi_uchar_type_emitter.h"
|
||||
#include "type/hdi_ushort_type_emitter.h"
|
||||
#include "type/hdi_uint_type_emitter.h"
|
||||
#include "type/hdi_ulong_type_emitter.h"
|
||||
#include "type/hdi_string_type_emitter.h"
|
||||
#include "type/hdi_fd_type_emitter.h"
|
||||
#include "type/hdi_seq_type_emitter.h"
|
||||
#include "type/hdi_interface_type_emitter.h"
|
||||
#include "type/hdi_map_type_emitter.h"
|
||||
#include "type/hdi_array_type_emitter.h"
|
||||
#include "type/hdi_enum_type_emitter.h"
|
||||
#include "type/hdi_struct_type_emitter.h"
|
||||
#include "type/hdi_union_type_emitter.h"
|
||||
#include "type/hdi_smq_type_emitter.h"
|
||||
#include "type/hdi_native_buffer_type_emitter.h"
|
||||
#include "type/hdi_pointer_type_emitter.h"
|
||||
|
||||
#include <cctype>
|
||||
#include "util/file.h"
|
||||
#include "util/options.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
HDICodeEmitter::TypeEmitterMap HDICodeEmitter::basicEmitters_ = {
|
||||
{TypeKind::TYPE_BOOLEAN, new HdiBooleanTypeEmitter() },
|
||||
{TypeKind::TYPE_BYTE, new HdiByteTypeEmitter() },
|
||||
{TypeKind::TYPE_SHORT, new HdiShortTypeEmitter() },
|
||||
{TypeKind::TYPE_INT, new HdiIntTypeEmitter() },
|
||||
{TypeKind::TYPE_LONG, new HdiLongTypeEmitter() },
|
||||
{TypeKind::TYPE_FLOAT, new HdiFloatTypeEmitter() },
|
||||
{TypeKind::TYPE_DOUBLE, new HdiDoubleTypeEmitter() },
|
||||
{TypeKind::TYPE_UCHAR, new HdiUcharTypeEmitter() },
|
||||
{TypeKind::TYPE_USHORT, new HdiUshortTypeEmitter() },
|
||||
{TypeKind::TYPE_UINT, new HdiUintTypeEmitter() },
|
||||
{TypeKind::TYPE_ULONG, new HdiUlongTypeEmitter() },
|
||||
{TypeKind::TYPE_STRING, new HdiStringTypeEmitter() },
|
||||
{TypeKind::TYPE_FILEDESCRIPTOR, new HdiFdTypeEmitter() },
|
||||
{TypeKind::TYPE_ASHMEM, new HdiAshmemTypeEmitter() },
|
||||
{TypeKind::TYPE_NATIVE_BUFFER, new HdiNativeBufferTypeEmitter() },
|
||||
{TypeKind::TYPE_POINTER, new HdiPointerTypeEmitter() },
|
||||
};
|
||||
|
||||
bool HDICodeEmitter::OutPut(const AutoPtr<AST> &ast, const std::string &targetDirectory, GenMode mode)
|
||||
{
|
||||
if (!Reset(ast, targetDirectory, mode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EmitCode();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HDICodeEmitter::Reset(const AutoPtr<AST> &ast, const std::string &targetDirectory, GenMode mode)
|
||||
{
|
||||
if (ast == nullptr || targetDirectory.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CleanData();
|
||||
|
||||
mode_ = mode;
|
||||
ast_ = ast;
|
||||
if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
|
||||
interface_ = ast_->GetInterfaceDef();
|
||||
interfaceName_ = interface_->GetName();
|
||||
std::string nameSpace = interface_->GetNamespace()->ToString();
|
||||
interfaceFullName_ = nameSpace + interfaceName_;
|
||||
baseName_ = StringHelper::StartWith(interfaceName_, "I") ? interfaceName_.substr(1) : interfaceName_;
|
||||
proxyName_ = baseName_ + "Proxy";
|
||||
proxyFullName_ = nameSpace + proxyName_;
|
||||
|
||||
stubName_ = baseName_ + "Stub";
|
||||
stubFullName_ = nameSpace + stubName_;
|
||||
|
||||
implName_ = baseName_ + "Service";
|
||||
implFullName_ = nameSpace + implName_;
|
||||
} else if (ast_->GetASTFileType() == ASTFileType::AST_TYPES) {
|
||||
baseName_ = ast_->GetName();
|
||||
} else if (ast_->GetASTFileType() == ASTFileType::AST_SEQUENCEABLE) {
|
||||
baseName_ = ast_->GetName();
|
||||
}
|
||||
|
||||
majorVerName_ = StringHelper::Format("%s_MAJOR_VERSION", ConstantName(interfaceName_).c_str());
|
||||
minorVerName_ = StringHelper::Format("%s_MINOR_VERSION", ConstantName(interfaceName_).c_str());
|
||||
|
||||
std::string prefix = StringHelper::Format("%c%s", tolower(baseName_[0]), baseName_.substr(1).c_str());
|
||||
HdiTypeEmitter::dataParcelName_ = prefix + "Data";
|
||||
HdiTypeEmitter::replyParcelName_ = prefix + "Reply";
|
||||
optionName_ = prefix + "Option";
|
||||
HdiTypeEmitter::errorCodeName_ = prefix + "Ret";
|
||||
flagOfSetMemName_ = prefix + "MemSet";
|
||||
|
||||
if (!ResolveDirectory(targetDirectory)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HDICodeEmitter::CleanData()
|
||||
{
|
||||
ast_ = nullptr;
|
||||
interface_ = nullptr;
|
||||
directory_ = "";
|
||||
interfaceName_ = "";
|
||||
interfaceFullName_ = "";
|
||||
baseName_ = "";
|
||||
proxyName_ = "";
|
||||
proxyFullName_ = "";
|
||||
stubName_ = "";
|
||||
stubFullName_ = "";
|
||||
implName_ = "";
|
||||
implFullName_ = "";
|
||||
HdiTypeEmitter::dataParcelName_ = "";
|
||||
HdiTypeEmitter::replyParcelName_ = "";
|
||||
optionName_ = "";
|
||||
HdiTypeEmitter::errorCodeName_ = "";
|
||||
}
|
||||
|
||||
std::string HDICodeEmitter::GetNameWithNamespace(AutoPtr<ASTNamespace> space, std::string name) const
|
||||
{
|
||||
std::vector<std::string> namespaceVec = StringHelper::Split(space->ToString(), ".");
|
||||
std::regex rVer("[V|v][0-9]+_[0-9]+");
|
||||
std::vector<std::string> result;
|
||||
bool findVersion = false;
|
||||
|
||||
std::string rootPackage = Options::GetInstance().GetRootPackage(space->ToString());
|
||||
size_t rootPackageNum = StringHelper::Split(rootPackage, ".").size();
|
||||
|
||||
for (size_t i = 0; i < namespaceVec.size(); i++) {
|
||||
std::string ns;
|
||||
if (i < rootPackageNum) {
|
||||
ns = StringHelper::StrToUpper(namespaceVec[i]);
|
||||
} else if (!findVersion && std::regex_match(namespaceVec[i].c_str(), rVer)) {
|
||||
ns = StringHelper::Replace(namespaceVec[i], 'v', 'V');
|
||||
findVersion = true;
|
||||
} else {
|
||||
if (findVersion) {
|
||||
ns = namespaceVec[i];
|
||||
} else {
|
||||
ns = PascalName(namespaceVec[i]);
|
||||
}
|
||||
}
|
||||
|
||||
result.emplace_back(ns);
|
||||
}
|
||||
StringBuilder sb;
|
||||
for (const auto &ns : result) {
|
||||
sb.AppendFormat("%s::", ns.c_str());
|
||||
}
|
||||
sb.Append(name);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
AutoPtr<HdiTypeEmitter> HDICodeEmitter::GetTypeEmitter(AutoPtr<ASTType> astType) const
|
||||
{
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter;
|
||||
auto basicTypePair = basicEmitters_.find(astType->GetTypeKind());
|
||||
if (basicTypePair != basicEmitters_.end()) {
|
||||
typeEmitter = (static_cast<HdiTypeEmitter*>(basicTypePair->second.Get()));
|
||||
}
|
||||
|
||||
if (typeEmitter == nullptr) {
|
||||
typeEmitter = NewTypeEmitter(astType);
|
||||
}
|
||||
|
||||
typeEmitter->SetName(astType->GetName());
|
||||
typeEmitter->SetPod(astType->IsPod());
|
||||
if (astType->IsSequenceableType() || astType->IsInterfaceType() ||
|
||||
astType->IsEnumType() || astType->IsStructType() || astType->IsUnionType()) {
|
||||
typeEmitter->SetTypeName(GetNameWithNamespace(astType->GetNamespace(), astType->GetName()));
|
||||
} else {
|
||||
typeEmitter->SetTypeName(astType->ToString());
|
||||
}
|
||||
|
||||
return typeEmitter;
|
||||
}
|
||||
|
||||
AutoPtr<HdiTypeEmitter> HDICodeEmitter::NewTypeEmitter(AutoPtr<ASTType> astType) const
|
||||
{
|
||||
switch (astType->GetTypeKind()) {
|
||||
case TypeKind::TYPE_MAP:
|
||||
return NewMapTypeEmitter(astType);
|
||||
case TypeKind::TYPE_ARRAY:
|
||||
return NewArrayTypeEmitter(astType);
|
||||
case TypeKind::TYPE_LIST:
|
||||
return NewListTypeEmitter(astType);
|
||||
case TypeKind::TYPE_ENUM:
|
||||
return NewEnumTypeEmitter(astType);
|
||||
case TypeKind::TYPE_STRUCT:
|
||||
return NewStructTypeEmitter(astType);
|
||||
case TypeKind::TYPE_UNION:
|
||||
return NewUnionTypeEmitter(astType);
|
||||
case TypeKind::TYPE_SMQ:
|
||||
return NewSmqTypeEmitter(astType);
|
||||
case TypeKind::TYPE_SEQUENCEABLE:
|
||||
return new HdiSeqTypeEmitter();
|
||||
case TypeKind::TYPE_INTERFACE:
|
||||
return new HdiInterfaceTypeEmitter();
|
||||
default: {
|
||||
// type not match, new a empty emitter
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = new HdiTypeEmitter();
|
||||
return typeEmitter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AutoPtr<HdiTypeEmitter> HDICodeEmitter::NewMapTypeEmitter(AutoPtr<ASTType> astType) const
|
||||
{
|
||||
AutoPtr<HdiMapTypeEmitter> mapTypeEmitter = new HdiMapTypeEmitter();
|
||||
AutoPtr<ASTType> keyType = (static_cast<ASTMapType*>(astType.Get()))->GetKeyType();
|
||||
AutoPtr<ASTType> valueType = (static_cast<ASTMapType*>(astType.Get()))->GetValueType();
|
||||
AutoPtr<HdiTypeEmitter> keyEmitter = GetTypeEmitter(keyType);
|
||||
AutoPtr<HdiTypeEmitter> valueEmitter = GetTypeEmitter(valueType);
|
||||
mapTypeEmitter->SetKeyEmitter(keyEmitter);
|
||||
mapTypeEmitter->SetValueEmitter(valueEmitter);
|
||||
return mapTypeEmitter.Get();
|
||||
}
|
||||
|
||||
AutoPtr<HdiTypeEmitter> HDICodeEmitter::NewArrayTypeEmitter(AutoPtr<ASTType> astType) const
|
||||
{
|
||||
AutoPtr<HdiArrayTypeEmitter> arrayTypeEmitter = new HdiArrayTypeEmitter();
|
||||
AutoPtr<ASTType> elemType = (static_cast<ASTArrayType*>(astType.Get()))->GetElementType();
|
||||
AutoPtr<HdiTypeEmitter> elemEmitter = GetTypeEmitter(elemType);
|
||||
arrayTypeEmitter->SetElementEmitter(elemEmitter);
|
||||
return arrayTypeEmitter.Get();
|
||||
}
|
||||
|
||||
AutoPtr<HdiTypeEmitter> HDICodeEmitter::NewListTypeEmitter(AutoPtr<ASTType> astType) const
|
||||
{
|
||||
AutoPtr<HdiListTypeEmitter> listTypeEmitter = new HdiListTypeEmitter();
|
||||
AutoPtr<ASTType> elemType = (static_cast<ASTListType*>(astType.Get()))->GetElementType();
|
||||
AutoPtr<HdiTypeEmitter> elemEmitter = GetTypeEmitter(elemType);
|
||||
listTypeEmitter->SetElementEmitter(elemEmitter);
|
||||
return listTypeEmitter.Get();
|
||||
}
|
||||
|
||||
AutoPtr<HdiTypeEmitter> HDICodeEmitter::NewEnumTypeEmitter(AutoPtr<ASTType> astType) const
|
||||
{
|
||||
AutoPtr<HdiEnumTypeEmitter> enumTypeEmitter = new HdiEnumTypeEmitter();
|
||||
AutoPtr<ASTEnumType> enumType = (static_cast<ASTEnumType*>(astType.Get()));
|
||||
if (enumType->GetBaseType() != nullptr) {
|
||||
AutoPtr<HdiTypeEmitter> baseTypeEmitter = GetTypeEmitter(enumType->GetBaseType());
|
||||
enumTypeEmitter->SetBaseTypeName(baseTypeEmitter->EmitCppType());
|
||||
}
|
||||
for (auto it : enumType->GetMembers()) {
|
||||
if (it->GetExprValue() == nullptr) {
|
||||
enumTypeEmitter->AddMember(new HdiEnumValueEmitter(it->GetName(), std::string("")));
|
||||
} else {
|
||||
enumTypeEmitter->AddMember(new HdiEnumValueEmitter(it->GetName(), it->GetExprValue()->EmitCode()));
|
||||
}
|
||||
}
|
||||
return enumTypeEmitter.Get();
|
||||
}
|
||||
|
||||
AutoPtr<HdiTypeEmitter> HDICodeEmitter::NewStructTypeEmitter(AutoPtr<ASTType> astType) const
|
||||
{
|
||||
AutoPtr<HdiStructTypeEmitter> structTypeEmitter = new HdiStructTypeEmitter();
|
||||
AutoPtr<ASTStructType> structType = (static_cast<ASTStructType*>(astType.Get()));
|
||||
for (auto it : structType->GetMembers()) {
|
||||
structTypeEmitter->AddMember(std::get<0>(it), GetTypeEmitter(std::get<1>(it)));
|
||||
}
|
||||
return structTypeEmitter.Get();
|
||||
}
|
||||
|
||||
AutoPtr<HdiTypeEmitter> HDICodeEmitter::NewUnionTypeEmitter(AutoPtr<ASTType> astType) const
|
||||
{
|
||||
AutoPtr<HdiUnionTypeEmitter> unionTypeEmitter = new HdiUnionTypeEmitter();
|
||||
AutoPtr<ASTUnionType> unionType = (static_cast<ASTUnionType*>(astType.Get()));
|
||||
for (size_t i = 0; i < unionType->GetMemberNumber(); i++) {
|
||||
unionTypeEmitter->AddMember(unionType->GetMemberName(i), GetTypeEmitter(unionType->GetMemberType(i)));
|
||||
}
|
||||
return unionTypeEmitter.Get();
|
||||
}
|
||||
|
||||
AutoPtr<HdiTypeEmitter> HDICodeEmitter::NewSmqTypeEmitter(AutoPtr<ASTType> astType) const
|
||||
{
|
||||
AutoPtr<HdiSmqTypeEmitter> smqTypeEmitter = new HdiSmqTypeEmitter();
|
||||
AutoPtr<ASTType> innerType = (static_cast<ASTSmqType*>(astType.Get()))->GetInnerType();
|
||||
AutoPtr<HdiTypeEmitter> innerTypeEmitter = GetTypeEmitter(innerType);
|
||||
smqTypeEmitter->SetInnerTypeEmitter(innerTypeEmitter);
|
||||
return smqTypeEmitter.Get();
|
||||
}
|
||||
|
||||
void HDICodeEmitter::EmitUtilMethods(StringBuilder &sb, bool isDecl)
|
||||
{
|
||||
(void)sb;
|
||||
(void)isDecl;
|
||||
}
|
||||
|
||||
void HDICodeEmitter::EmitUtilMethodMap(StringBuilder &sb, const UtilMethodMap &methods)
|
||||
{
|
||||
// generator util methods
|
||||
for (const auto &methodPair : methods) {
|
||||
sb.Append(methodPair.second);
|
||||
}
|
||||
}
|
||||
|
||||
void HDICodeEmitter::EmitInterfaceBuffSizeMacro(StringBuilder &sb) const
|
||||
{
|
||||
sb.AppendFormat("#ifndef %s\n", MAX_BUFF_SIZE_MACRO);
|
||||
sb.AppendFormat("#define %s (%s)\n", MAX_BUFF_SIZE_MACRO, MAX_BUFF_SIZE_VALUE);
|
||||
sb.Append("#endif\n\n");
|
||||
|
||||
sb.AppendFormat("#ifndef %s\n", CHECK_VALUE_RETURN_MACRO);
|
||||
sb.AppendFormat("#define %s(lv, compare, rv, ret) do { \\\n", CHECK_VALUE_RETURN_MACRO);
|
||||
sb.Append(TAB).Append("if ((lv) compare (rv)) { \\\n");
|
||||
sb.Append(TAB).Append(TAB).Append("return ret; \\\n");
|
||||
sb.Append(TAB).Append("} \\\n");
|
||||
sb.Append("} while (false)\n");
|
||||
sb.Append("#endif\n\n");
|
||||
|
||||
sb.AppendFormat("#ifndef %s\n", CHECK_VALUE_RET_GOTO_MACRO);
|
||||
sb.AppendFormat("#define %s(lv, compare, rv, ret, value, table) do { \\\n", CHECK_VALUE_RET_GOTO_MACRO);
|
||||
sb.Append(TAB).Append("if ((lv) compare (rv)) { \\\n");
|
||||
sb.Append(TAB).Append(TAB).Append("ret = value; \\\n");
|
||||
sb.Append(TAB).Append(TAB).Append("goto table; \\\n");
|
||||
sb.Append(TAB).Append("} \\\n");
|
||||
sb.Append("} while (false)\n");
|
||||
sb.Append("#endif\n");
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
78
idl_tool_2/codegen/HDI/hdi_code_emitter.h
Normal file
78
idl_tool_2/codegen/HDI/hdi_code_emitter.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_HDI_CODE_EMITTER_H
|
||||
#define OHOS_IDL_HDI_CODE_EMITTER_H
|
||||
|
||||
#include "codegen/code_emitter.h"
|
||||
#include "hdi_type_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
class HDICodeEmitter : public CodeEmitter {
|
||||
public:
|
||||
using TypeEmitterMap = std::unordered_map<TypeKind, AutoPtr<HdiTypeEmitter>>;
|
||||
|
||||
~HDICodeEmitter() override = default;
|
||||
|
||||
bool OutPut(const AutoPtr<AST> &ast, const std::string &targetDirectory, GenMode mode) override;
|
||||
|
||||
virtual void EmitUtilMethods(StringBuilder &sb, bool isDecl);
|
||||
|
||||
protected:
|
||||
bool Reset(const AutoPtr<AST> &ast, const std::string &targetDirectory, GenMode mode);
|
||||
|
||||
void CleanData();
|
||||
|
||||
AutoPtr<HdiTypeEmitter> GetTypeEmitter(AutoPtr<ASTType> astType) const;
|
||||
|
||||
void EmitInterfaceBuffSizeMacro(StringBuilder &sb) const;
|
||||
|
||||
void EmitUtilMethodMap(StringBuilder &sb, const UtilMethodMap &methods);
|
||||
|
||||
GenMode mode_ = GenMode::IPC;
|
||||
std::string implName_;
|
||||
std::string implFullName_;
|
||||
std::string majorVerName_;
|
||||
std::string minorVerName_;
|
||||
|
||||
std::string flagOfSetMemName_;
|
||||
std::string optionName_;
|
||||
|
||||
private:
|
||||
std::string GetNameWithNamespace(AutoPtr<ASTNamespace> space, std::string name) const;
|
||||
|
||||
AutoPtr<HdiTypeEmitter> NewTypeEmitter(AutoPtr<ASTType> astType) const;
|
||||
|
||||
AutoPtr<HdiTypeEmitter> NewMapTypeEmitter(AutoPtr<ASTType> astType) const;
|
||||
|
||||
AutoPtr<HdiTypeEmitter> NewArrayTypeEmitter(AutoPtr<ASTType> astType) const;
|
||||
|
||||
AutoPtr<HdiTypeEmitter> NewListTypeEmitter(AutoPtr<ASTType> astType) const;
|
||||
|
||||
AutoPtr<HdiTypeEmitter> NewEnumTypeEmitter(AutoPtr<ASTType> astType) const;
|
||||
|
||||
AutoPtr<HdiTypeEmitter> NewStructTypeEmitter(AutoPtr<ASTType> astType) const;
|
||||
|
||||
AutoPtr<HdiTypeEmitter> NewUnionTypeEmitter(AutoPtr<ASTType> astType) const;
|
||||
|
||||
AutoPtr<HdiTypeEmitter> NewSmqTypeEmitter(AutoPtr<ASTType> astType) const;
|
||||
|
||||
static TypeEmitterMap basicEmitters_;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_CODE_EMITTER_H
|
339
idl_tool_2/codegen/HDI/hdi_code_generator.cpp
Normal file
339
idl_tool_2/codegen/HDI/hdi_code_generator.cpp
Normal file
@ -0,0 +1,339 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "hdi_code_generator.h"
|
||||
#include "codegen/HDI/c/c_client_proxy_code_emitter.h"
|
||||
#include "codegen/HDI/c/c_custom_types_code_emitter.h"
|
||||
#include "codegen/HDI/c/c_interface_code_emitter.h"
|
||||
#include "codegen/HDI/c/c_service_driver_code_emitter.h"
|
||||
#include "codegen/HDI/c/c_service_impl_code_emitter.h"
|
||||
#include "codegen/HDI/c/c_service_stub_code_emitter.h"
|
||||
#include "codegen/HDI/cpp/cpp_client_proxy_code_emitter.h"
|
||||
#include "codegen/HDI/cpp/cpp_custom_types_code_emitter.h"
|
||||
#include "codegen/HDI/cpp/cpp_interface_code_emitter.h"
|
||||
#include "codegen/HDI/cpp/cpp_service_driver_code_emitter.h"
|
||||
#include "codegen/HDI/cpp/cpp_service_impl_code_emitter.h"
|
||||
#include "codegen/HDI/cpp/cpp_service_stub_code_emitter.h"
|
||||
#include "codegen/HDI/java/java_client_interface_code_emitter.h"
|
||||
#include "codegen/HDI/java/java_client_proxy_code_emitter.h"
|
||||
#include "util/options.h"
|
||||
#include "util/logger.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
HDICodeGenerator::GeneratePolicies HDICodeGenerator::policies_ = {
|
||||
{
|
||||
SystemLevel::MINI,
|
||||
{
|
||||
{
|
||||
GenMode::LOW,
|
||||
{
|
||||
{Language::C, HDICodeGenerator::GenLowCCode}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
SystemLevel::LITE,
|
||||
{
|
||||
{
|
||||
GenMode::KERNEL,
|
||||
{
|
||||
{Language::C, HDICodeGenerator::GenKernelCode}
|
||||
}
|
||||
},
|
||||
{
|
||||
GenMode::PASSTHROUGH,
|
||||
{
|
||||
{Language::C, HDICodeGenerator::GenPassthroughCCode},
|
||||
{Language::CPP, HDICodeGenerator::GenPassthroughCppCode}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
SystemLevel::FULL,
|
||||
{
|
||||
{
|
||||
GenMode::KERNEL,
|
||||
{
|
||||
{Language::C, HDICodeGenerator::GenKernelCode}
|
||||
}
|
||||
},
|
||||
{
|
||||
GenMode::PASSTHROUGH,
|
||||
{
|
||||
{Language::C, HDICodeGenerator::GenPassthroughCCode},
|
||||
{Language::CPP, HDICodeGenerator::GenPassthroughCppCode}
|
||||
}
|
||||
},
|
||||
{
|
||||
GenMode::IPC,
|
||||
{
|
||||
{Language::C, HDICodeGenerator::GenIpcCCode},
|
||||
{Language::CPP, HDICodeGenerator::GenIpcCppCode},
|
||||
{Language::JAVA, HDICodeGenerator::GenIpcJavaCode}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CodeEmitMap HDICodeGenerator::cCodeEmitters_ = {
|
||||
{"types", new CCustomTypesCodeEmitter() },
|
||||
{"interface", new CInterfaceCodeEmitter() },
|
||||
{"proxy", new CClientProxyCodeEmitter() },
|
||||
{"driver", new CServiceDriverCodeEmitter()},
|
||||
{"stub", new CServiceStubCodeEmitter() },
|
||||
{"service", new CServiceImplCodeEmitter() },
|
||||
};
|
||||
|
||||
CodeEmitMap HDICodeGenerator::cppCodeEmitters_ = {
|
||||
{"types", new CppCustomTypesCodeEmitter() },
|
||||
{"interface", new CppInterfaceCodeEmitter() },
|
||||
{"proxy", new CppClientProxyCodeEmitter() },
|
||||
{"driver", new CppServiceDriverCodeEmitter()},
|
||||
{"stub", new CppServiceStubCodeEmitter() },
|
||||
{"service", new CppServiceImplCodeEmitter() },
|
||||
};
|
||||
|
||||
CodeEmitMap HDICodeGenerator::javaCodeEmitters_ = {
|
||||
{"interface", new JavaClientInterfaceCodeEmitter()},
|
||||
{"proxy", new JavaClientProxyCodeEmitter() },
|
||||
};
|
||||
|
||||
bool HDICodeGenerator::DoGenerate(const StrAstMap &allAst)
|
||||
{
|
||||
auto genCodeFunc = GetCodeGenPoilcy();
|
||||
if (!genCodeFunc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string outDir = Options::GetInstance().GetGenerationDirectory();
|
||||
std::set<std::string> sourceFile = Options::GetInstance().GetSourceFiles();
|
||||
Language language = Options::GetInstance().GetLanguage();
|
||||
if (language == Language::CPP) {
|
||||
for (const auto &ast : allAst) {
|
||||
if (sourceFile.find(ast.second->GetIdlFilePath()) != sourceFile.end()) {
|
||||
genCodeFunc(ast.second, outDir);
|
||||
}
|
||||
}
|
||||
} else if (language == Language::C) {
|
||||
for (const auto &ast : allAst) {
|
||||
genCodeFunc(ast.second, outDir);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CodeGenFunc HDICodeGenerator::GetCodeGenPoilcy()
|
||||
{
|
||||
auto systemPolicies = policies_.find(Options::GetInstance().GetSystemLevel());
|
||||
if (systemPolicies == policies_.end()) {
|
||||
Logger::E(TAG, "the system level is not supported, please check option");
|
||||
return CodeGenFunc{};
|
||||
}
|
||||
|
||||
auto genModePolicies = systemPolicies->second;
|
||||
auto genModeIter = genModePolicies.find(Options::GetInstance().GetGenMode());
|
||||
if (genModeIter == genModePolicies.end()) {
|
||||
Logger::E(TAG, "the generate mode is not supported, please check option");
|
||||
return CodeGenFunc{};
|
||||
}
|
||||
|
||||
auto languagePolicies = genModeIter->second;
|
||||
auto languageIter = languagePolicies.find(Options::GetInstance().GetLanguage());
|
||||
if (languageIter == languagePolicies.end()) {
|
||||
Logger::E(TAG, "the language is not supported, please check option");
|
||||
return CodeGenFunc{};
|
||||
}
|
||||
return languageIter->second;
|
||||
}
|
||||
|
||||
void HDICodeGenerator::GenIpcCCode(const AutoPtr<AST> &ast, const std::string &outDir)
|
||||
{
|
||||
GenMode mode = GenMode::IPC;
|
||||
switch (ast->GetASTFileType()) {
|
||||
case ASTFileType::AST_TYPES: {
|
||||
cCodeEmitters_["types"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
case ASTFileType::AST_IFACE: {
|
||||
cCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
|
||||
cCodeEmitters_["proxy"]->OutPut(ast, outDir, mode);
|
||||
cCodeEmitters_["driver"]->OutPut(ast, outDir, mode);
|
||||
cCodeEmitters_["stub"]->OutPut(ast, outDir, mode);
|
||||
cCodeEmitters_["service"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
case ASTFileType::AST_ICALLBACK: {
|
||||
cCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
|
||||
cCodeEmitters_["proxy"]->OutPut(ast, outDir, mode);
|
||||
cCodeEmitters_["stub"]->OutPut(ast, outDir, mode);
|
||||
cCodeEmitters_["service"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HDICodeGenerator::GenIpcCppCode(const AutoPtr<AST> &ast, const std::string &outDir)
|
||||
{
|
||||
GenMode mode = GenMode::IPC;
|
||||
switch (ast->GetASTFileType()) {
|
||||
case ASTFileType::AST_TYPES: {
|
||||
cppCodeEmitters_["types"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
case ASTFileType::AST_IFACE: {
|
||||
cppCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
|
||||
cppCodeEmitters_["proxy"]->OutPut(ast, outDir, mode);
|
||||
cppCodeEmitters_["driver"]->OutPut(ast, outDir, mode);
|
||||
cppCodeEmitters_["stub"]->OutPut(ast, outDir, mode);
|
||||
cppCodeEmitters_["service"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
case ASTFileType::AST_ICALLBACK: {
|
||||
cppCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
|
||||
cppCodeEmitters_["proxy"]->OutPut(ast, outDir, mode);
|
||||
cppCodeEmitters_["stub"]->OutPut(ast, outDir, mode);
|
||||
cppCodeEmitters_["service"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HDICodeGenerator::GenIpcJavaCode(const AutoPtr<AST> &ast, const std::string &outDir)
|
||||
{
|
||||
GenMode mode = GenMode::IPC;
|
||||
switch (ast->GetASTFileType()) {
|
||||
case ASTFileType::AST_TYPES: {
|
||||
javaCodeEmitters_["types"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
case ASTFileType::AST_IFACE:
|
||||
case ASTFileType::AST_ICALLBACK: {
|
||||
javaCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
|
||||
javaCodeEmitters_["proxy"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HDICodeGenerator::GenPassthroughCCode(const AutoPtr<AST> &ast, const std::string &outDir)
|
||||
{
|
||||
GenMode mode = GenMode::PASSTHROUGH;
|
||||
switch (ast->GetASTFileType()) {
|
||||
case ASTFileType::AST_TYPES: {
|
||||
cCodeEmitters_["types"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
case ASTFileType::AST_IFACE: {
|
||||
cCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
|
||||
cCodeEmitters_["proxy"]->OutPut(ast, outDir, mode);
|
||||
cCodeEmitters_["service"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
case ASTFileType::AST_ICALLBACK: {
|
||||
cCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
|
||||
cCodeEmitters_["service"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HDICodeGenerator::GenPassthroughCppCode(const AutoPtr<AST> &ast, const std::string &outDir)
|
||||
{
|
||||
GenMode mode = GenMode::PASSTHROUGH;
|
||||
switch (ast->GetASTFileType()) {
|
||||
case ASTFileType::AST_TYPES: {
|
||||
cppCodeEmitters_["types"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
case ASTFileType::AST_IFACE: {
|
||||
cppCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
|
||||
cppCodeEmitters_["proxy"]->OutPut(ast, outDir, mode);
|
||||
cppCodeEmitters_["service"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
case ASTFileType::AST_ICALLBACK: {
|
||||
cppCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
|
||||
cppCodeEmitters_["service"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HDICodeGenerator::GenKernelCode(const AutoPtr<AST> &ast, const std::string &outDir)
|
||||
{
|
||||
GenMode mode = GenMode::KERNEL;
|
||||
switch (ast->GetASTFileType()) {
|
||||
case ASTFileType::AST_TYPES: {
|
||||
cCodeEmitters_["types"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
case ASTFileType::AST_IFACE: {
|
||||
cCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
|
||||
cCodeEmitters_["proxy"]->OutPut(ast, outDir, mode);
|
||||
cCodeEmitters_["driver"]->OutPut(ast, outDir, mode);
|
||||
cCodeEmitters_["stub"]->OutPut(ast, outDir, mode);
|
||||
cCodeEmitters_["service"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HDICodeGenerator::GenLowCCode(const AutoPtr<AST> &ast, const std::string &outDir)
|
||||
{
|
||||
GenMode mode = GenMode::LOW;
|
||||
switch (ast->GetASTFileType()) {
|
||||
case ASTFileType::AST_TYPES: {
|
||||
cCodeEmitters_["types"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
case ASTFileType::AST_IFACE: {
|
||||
cCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
|
||||
cCodeEmitters_["driver"]->OutPut(ast, outDir, mode);
|
||||
cCodeEmitters_["service"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
case ASTFileType::AST_ICALLBACK: {
|
||||
cCodeEmitters_["interface"]->OutPut(ast, outDir, mode);
|
||||
cCodeEmitters_["service"]->OutPut(ast, outDir, mode);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HDICodeGenerator::GeneratorInit()
|
||||
{
|
||||
CodegenBuilder::GetInstance().GeneratorRegister(InterfaceType::HDI, new HDICodeGenerator());
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
56
idl_tool_2/codegen/HDI/hdi_code_generator.h
Normal file
56
idl_tool_2/codegen/HDI/hdi_code_generator.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_HDI_CODEGENERATOR_H
|
||||
#define OHOS_IDL_HDI_CODEGENERATOR_H
|
||||
|
||||
#include "codegen/code_generator.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
|
||||
class HDICodeGenerator : public CodeGenerator {
|
||||
public:
|
||||
using GeneratePolicies = std::map<SystemLevel, std::map<GenMode, std::map<Language, CodeGenFunc>>>;
|
||||
bool DoGenerate(const StrAstMap &allAst) override;
|
||||
|
||||
private:
|
||||
static CodeGenFunc GetCodeGenPoilcy();
|
||||
|
||||
static void GenIpcCCode(const AutoPtr<AST> &ast, const std::string &outDir);
|
||||
|
||||
static void GenIpcCppCode(const AutoPtr<AST> &ast, const std::string &outDir);
|
||||
|
||||
static void GenIpcJavaCode(const AutoPtr<AST> &ast, const std::string &outDir);
|
||||
|
||||
static void GenPassthroughCCode(const AutoPtr<AST> &ast, const std::string &outDir);
|
||||
|
||||
static void GenPassthroughCppCode(const AutoPtr<AST> &ast, const std::string &outDir);
|
||||
|
||||
static void GenKernelCode(const AutoPtr<AST> &ast, const std::string &outDir);
|
||||
|
||||
static void GenLowCCode(const AutoPtr<AST> &ast, const std::string &outDir);
|
||||
|
||||
static void GeneratorInit() __attribute__((constructor));
|
||||
|
||||
static GeneratePolicies policies_;
|
||||
static CodeEmitMap cCodeEmitters_;
|
||||
static CodeEmitMap cppCodeEmitters_;
|
||||
static CodeEmitMap javaCodeEmitters_;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_CODEGENERATOR_H
|
215
idl_tool_2/codegen/HDI/hdi_type_emitter.cpp
Normal file
215
idl_tool_2/codegen/HDI/hdi_type_emitter.cpp
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "hdi_type_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
std::string HdiTypeEmitter::dataParcelName_;
|
||||
std::string HdiTypeEmitter::replyParcelName_;
|
||||
std::string HdiTypeEmitter::errorCodeName_;
|
||||
bool HdiTypeEmitter::IsPod() const
|
||||
{
|
||||
return isPod_;
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::SetPod(const bool &isPod)
|
||||
{
|
||||
isPod_ = isPod;
|
||||
}
|
||||
|
||||
TypeKind HdiTypeEmitter::GetTypeKind()
|
||||
{
|
||||
return TypeKind::TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::SetTypeName(const std::string &name)
|
||||
{
|
||||
typeName_ = name;
|
||||
}
|
||||
|
||||
std::string HdiTypeEmitter::GetTypeName()
|
||||
{
|
||||
return typeName_;
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::SetName(const std::string &name)
|
||||
{
|
||||
name_ = name;
|
||||
}
|
||||
|
||||
std::string HdiTypeEmitter::GetName()
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
std::string HdiTypeEmitter::EmitCType(TypeMode mode) const
|
||||
{
|
||||
return "unknow";
|
||||
}
|
||||
|
||||
std::string HdiTypeEmitter::EmitCppType(TypeMode mode) const
|
||||
{
|
||||
return "unknow";
|
||||
}
|
||||
|
||||
std::string HdiTypeEmitter::EmitJavaType(TypeMode mode, bool isInnerType) const
|
||||
{
|
||||
return "unknow";
|
||||
}
|
||||
|
||||
std::string HdiTypeEmitter::EmitCTypeDecl() const
|
||||
{
|
||||
StringBuilder sb;
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
std::string HdiTypeEmitter::EmitCppTypeDecl() const
|
||||
{
|
||||
StringBuilder sb;
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
std::string HdiTypeEmitter::EmitJavaTypeDecl() const
|
||||
{
|
||||
StringBuilder sb;
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitCWriteVar(TypeMode mode, const std::string &name,
|
||||
const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("//Writing \"%s\" type of data is not supported\n", name_.c_str());
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitCProxyWriteOutVar(const std::string &name, const std::string &gotoLabel, StringBuilder &sb,
|
||||
const std::string &prefix) const
|
||||
{
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitCProxyReadVar(const std::string &name, bool isInnerType, const std::string &gotoLabel,
|
||||
StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("//Reading \"%s\" type of data is not supported\n", name_.c_str());
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitCStubReadVar(const std::string &name, const std::string &gotoLabel, StringBuilder &sb,
|
||||
const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("//Reading \"%s\" type of data is not supported\n", name_.c_str());
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitCStubReadOutVar(const std::string &memFlagName, const std::string &name,
|
||||
const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("//Reading \"%s\" type of data is not supported\n", name_.c_str());
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitCppWriteVar(const std::string &parcelName, const std::string &name,
|
||||
StringBuilder &sb, const std::string &prefix, unsigned int innerLevel) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("//Writing \"%s\" type of data is not supported\n", name_.c_str());
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitCppReadVar(const std::string &name, StringBuilder &sb, const std::string &prefix,
|
||||
TypeMode mode, unsigned int innerLevel) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("//Reading \"%s\" type of data is not supported\n", name_.c_str());
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitCMarshalling(const std::string &name, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("//Writing \"%s\" type of data is not supported\n", name_.c_str());
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitCUnMarshalling(const std::string &name, const std::string &gotoLabel,
|
||||
StringBuilder &sb, const std::string &prefix, std::vector<std::string> &freeObjStatements) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("//Reading \"%s\" type of data is not supported\n", name_.c_str());
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitFreeStatements(
|
||||
const std::vector<std::string> &freeObjStatements, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
for (auto it = freeObjStatements.rbegin(); it != freeObjStatements.rend(); it++) {
|
||||
sb.Append(prefix).Append(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitCppMarshalling(const std::string &parcelName, const std::string &name,
|
||||
StringBuilder &sb, const std::string &prefix, unsigned int innerLevel) const
|
||||
{
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitCppUnMarshalling(const std::string &parcelName, const std::string &name,
|
||||
StringBuilder &sb, const std::string &prefix, unsigned int innerLevel) const
|
||||
{
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitMemoryRecycle(
|
||||
const std::string &name, bool ownership, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
// only std::string, Array, List, struct and union type need recycle memory
|
||||
(void)name;
|
||||
(void)ownership;
|
||||
(void)sb;
|
||||
(void)prefix;
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitJavaWriteVar(const std::string &parcelName, const std::string &name,
|
||||
StringBuilder &sb, const std::string &prefix, TypeMode mode) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("//Writing \"%s\" type of data is not supported\n", name_.c_str());
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitJavaReadVar(
|
||||
const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("//Reading \"%s\" type of data is not supported\n", name_.c_str());
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitJavaReadInnerVar(const std::string &parcelName, const std::string &name, bool isInner,
|
||||
StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("//Reading \"%s\" type of data is not supported\n", name_.c_str());
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitCWriteMethods(UtilMethodMap &methods, const std::string &prefix,
|
||||
const std::string &methodPrefix, bool isDecl) const
|
||||
{
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitCReadMethods(UtilMethodMap &methods, const std::string &prefix,
|
||||
const std::string &methodPrefix, bool isDecl) const
|
||||
{
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitCStubReadMethods(UtilMethodMap &methods, const std::string &prefix,
|
||||
const std::string &methodPrefix, bool isDecl) const
|
||||
{
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitCppWriteMethods(UtilMethodMap &methods, const std::string &prefix,
|
||||
const std::string &methodPrefix, bool isDecl) const
|
||||
{
|
||||
}
|
||||
|
||||
void HdiTypeEmitter::EmitCppReadMethods(UtilMethodMap &methods, const std::string &prefix,
|
||||
const std::string &methodPrefix, bool isDecl) const
|
||||
{
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
132
idl_tool_2/codegen/HDI/hdi_type_emitter.h
Normal file
132
idl_tool_2/codegen/HDI/hdi_type_emitter.h
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_HDI_TYPE_EMITTER_H
|
||||
#define OHOS_IDL_HDI_TYPE_EMITTER_H
|
||||
|
||||
#include <map>
|
||||
#include "ast/ast_type.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
constexpr const char *MAX_BUFF_SIZE_MACRO = "HDI_BUFF_MAX_SIZE";
|
||||
constexpr const char *MAX_BUFF_SIZE_VALUE = "1024 * 200"; // 200KB
|
||||
constexpr const char *CHECK_VALUE_RETURN_MACRO = "HDI_CHECK_VALUE_RETURN";
|
||||
constexpr const char *CHECK_VALUE_RET_GOTO_MACRO = "HDI_CHECK_VALUE_RET_GOTO";
|
||||
|
||||
using UtilMethodMap = std::unordered_map<std::string, std::string>;
|
||||
class HdiTypeEmitter : public LightRefCountBase {
|
||||
public:
|
||||
bool IsPod() const;
|
||||
|
||||
void SetPod(const bool &isPod);
|
||||
|
||||
virtual TypeKind GetTypeKind();
|
||||
|
||||
void SetTypeName(const std::string &name);
|
||||
|
||||
std::string GetTypeName();
|
||||
|
||||
void SetName(const std::string &name);
|
||||
|
||||
std::string GetName();
|
||||
|
||||
virtual std::string EmitCppType(TypeMode mode = TypeMode::NO_MODE) const;
|
||||
|
||||
virtual std::string EmitCType(TypeMode mode = TypeMode::NO_MODE) const;
|
||||
|
||||
virtual std::string EmitJavaType(TypeMode mode, bool isInnerType = false) const;
|
||||
|
||||
virtual std::string EmitCTypeDecl() const;
|
||||
|
||||
virtual std::string EmitCppTypeDecl() const;
|
||||
|
||||
virtual std::string EmitJavaTypeDecl() const;
|
||||
|
||||
virtual void EmitCWriteVar(TypeMode mode, const std::string &name, const std::string &gotoLabel,
|
||||
StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
virtual void EmitCProxyWriteOutVar(const std::string &name, const std::string &gotoLabel, StringBuilder &sb,
|
||||
const std::string &prefix) const;
|
||||
|
||||
virtual void EmitCProxyReadVar(const std::string &name, bool isInnerType, const std::string &gotoLabel,
|
||||
StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
virtual void EmitCStubReadVar(const std::string &name, const std::string &gotoLabel, StringBuilder &sb,
|
||||
const std::string &prefix) const;
|
||||
|
||||
virtual void EmitCStubReadOutVar(const std::string &memFlagName, const std::string &name,
|
||||
const std::string &gotoLabel, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
virtual void EmitCppWriteVar(const std::string &parcelName, const std::string &name, StringBuilder &sb,
|
||||
const std::string &prefix, unsigned int innerLevel = 0) const;
|
||||
|
||||
virtual void EmitCppReadVar(const std::string &name, StringBuilder &sb, const std::string &prefix,
|
||||
TypeMode mode, unsigned int innerLevel = 0) const;
|
||||
|
||||
virtual void EmitCMarshalling(const std::string &name, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
virtual void EmitCUnMarshalling(const std::string &name, const std::string &gotoLabel, StringBuilder &sb,
|
||||
const std::string &prefix, std::vector<std::string> &freeObjStatements) const;
|
||||
|
||||
virtual void EmitCWriteMethods(UtilMethodMap &methods, const std::string &prefix,
|
||||
const std::string &methodPrefix, bool isDecl) const;
|
||||
|
||||
virtual void EmitCppWriteMethods(UtilMethodMap &methods, const std::string &prefix,
|
||||
const std::string &methodPrefix, bool isDecl) const;
|
||||
|
||||
virtual void EmitCReadMethods(UtilMethodMap &methods, const std::string &prefix,
|
||||
const std::string &methodPrefix, bool isDecl) const;
|
||||
|
||||
virtual void EmitCppReadMethods(UtilMethodMap &methods, const std::string &prefix,
|
||||
const std::string &methodPrefix, bool isDecl) const;
|
||||
|
||||
virtual void EmitCStubReadMethods(UtilMethodMap &methods, const std::string &prefix,
|
||||
const std::string &methodPrefix, bool isDecl) const;
|
||||
|
||||
void EmitFreeStatements(
|
||||
const std::vector<std::string> &freeObjStatements, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
virtual void EmitCppMarshalling(const std::string &parcelName, const std::string &name, StringBuilder &sb,
|
||||
const std::string &prefix, unsigned int innerLevel = 0) const;
|
||||
|
||||
virtual void EmitCppUnMarshalling(const std::string &parcelName, const std::string &name, StringBuilder &sb,
|
||||
const std::string &prefix, unsigned int innerLevel = 0) const;
|
||||
|
||||
virtual void EmitMemoryRecycle(
|
||||
const std::string &name, bool ownership, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
virtual void EmitJavaWriteVar(const std::string &parcelName, const std::string &name, StringBuilder &sb,
|
||||
const std::string &prefix, TypeMode mode = TypeMode::NO_MODE) const;
|
||||
|
||||
virtual void EmitJavaReadVar(
|
||||
const std::string &parcelName, const std::string &name, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
virtual void EmitJavaReadInnerVar(const std::string &parcelName, const std::string &name, bool isInner,
|
||||
StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
static std::string dataParcelName_;
|
||||
static std::string replyParcelName_;
|
||||
static std::string errorCodeName_;
|
||||
|
||||
protected:
|
||||
bool isPod_;
|
||||
std::string typeName_;
|
||||
std::string name_;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_HDI_TYPE_EMITTER_H
|
102
idl_tool_2/codegen/HDI/java/hdi_java_code_emitter.cpp
Normal file
102
idl_tool_2/codegen/HDI/java/hdi_java_code_emitter.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "hdi_java_code_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
void HDIJavaCodeEmitter::EmitPackage(StringBuilder &sb)
|
||||
{
|
||||
sb.AppendFormat("package %s;\n", ast_->GetPackageName().c_str());
|
||||
}
|
||||
|
||||
void HDIJavaCodeEmitter::EmitInterfaceMethodCommands(StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
auto methods = interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel());
|
||||
for (size_t i = 0; i < methods.size(); i++) {
|
||||
sb.Append(prefix).AppendFormat("private static final int COMMAND_%s = IRemoteObject.MIN_TRANSACTION_ID + %d;\n",
|
||||
ConstantName(methods[i]->GetName()).c_str(), i);
|
||||
}
|
||||
}
|
||||
|
||||
std::string HDIJavaCodeEmitter::MethodName(const std::string &name) const
|
||||
{
|
||||
if (name.empty() || islower(name[0])) {
|
||||
return name;
|
||||
}
|
||||
return StringHelper::Format("%c%s", tolower(name[0]), name.substr(1).c_str());
|
||||
}
|
||||
|
||||
std::string HDIJavaCodeEmitter::SpecificationParam(StringBuilder ¶mSb, const std::string &prefix) const
|
||||
{
|
||||
size_t maxLineLen = 120;
|
||||
size_t replaceLen = 2;
|
||||
std::string paramStr = paramSb.ToString();
|
||||
size_t preIndex = 0;
|
||||
size_t curIndex = 0;
|
||||
|
||||
std::string insertStr = StringHelper::Format("\n%s", prefix.c_str());
|
||||
for (; curIndex < paramStr.size(); curIndex++) {
|
||||
if (curIndex == maxLineLen && preIndex > 0) {
|
||||
StringHelper::Replace(paramStr, preIndex, replaceLen, ",");
|
||||
paramStr.insert(preIndex + 1, insertStr);
|
||||
} else {
|
||||
if (paramStr[curIndex] == ',') {
|
||||
preIndex = curIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
return paramStr;
|
||||
}
|
||||
|
||||
void HDIJavaCodeEmitter::EmitInterfaceMethodParameter(
|
||||
const AutoPtr<ASTParameter> ¶m, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
std::string name = param->GetName();
|
||||
AutoPtr<ASTType> type = param->GetType();
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
|
||||
switch (type->GetTypeKind()) {
|
||||
case TypeKind::TYPE_BOOLEAN:
|
||||
case TypeKind::TYPE_BYTE:
|
||||
case TypeKind::TYPE_SHORT:
|
||||
case TypeKind::TYPE_INT:
|
||||
case TypeKind::TYPE_LONG:
|
||||
case TypeKind::TYPE_UCHAR:
|
||||
case TypeKind::TYPE_USHORT:
|
||||
case TypeKind::TYPE_UINT:
|
||||
case TypeKind::TYPE_ULONG:
|
||||
case TypeKind::TYPE_FLOAT:
|
||||
case TypeKind::TYPE_DOUBLE:
|
||||
case TypeKind::TYPE_ENUM:
|
||||
case TypeKind::TYPE_FILEDESCRIPTOR:
|
||||
case TypeKind::TYPE_STRING:
|
||||
case TypeKind::TYPE_SEQUENCEABLE:
|
||||
case TypeKind::TYPE_INTERFACE:
|
||||
case TypeKind::TYPE_STRUCT:
|
||||
case TypeKind::TYPE_UNION:
|
||||
case TypeKind::TYPE_POINTER:
|
||||
case TypeKind::TYPE_ARRAY:
|
||||
case TypeKind::TYPE_LIST:
|
||||
case TypeKind::TYPE_MAP: {
|
||||
sb.Append(prefix).AppendFormat("%s %s", typeEmitter->EmitJavaType(TypeMode::NO_MODE).c_str(), name.c_str());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
sb.Append(prefix).AppendFormat("unknow type %s", name.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
46
idl_tool_2/codegen/HDI/java/hdi_java_code_emitter.h
Normal file
46
idl_tool_2/codegen/HDI/java/hdi_java_code_emitter.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_JAVA_CODE_EMITTER_H
|
||||
#define OHOS_IDL_JAVA_CODE_EMITTER_H
|
||||
|
||||
#include <cctype>
|
||||
|
||||
#include "codegen/HDI/hdi_code_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
class HDIJavaCodeEmitter : public HDICodeEmitter {
|
||||
public:
|
||||
~HDIJavaCodeEmitter() override = default;
|
||||
|
||||
protected:
|
||||
bool CreateDirectory();
|
||||
|
||||
void EmitPackage(StringBuilder &sb);
|
||||
|
||||
void EmitInterfaceMethodCommands(StringBuilder &sb, const std::string &prefix) override;
|
||||
|
||||
std::string MethodName(const std::string &name) const;
|
||||
|
||||
std::string SpecificationParam(StringBuilder ¶mSb, const std::string &prefix) const;
|
||||
|
||||
void EmitInterfaceMethodParameter(const AutoPtr<ASTParameter> ¶m, StringBuilder &sb,
|
||||
const std::string &prefix) const;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_JAVA_CODE_EMITTER_H
|
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "java_client_interface_code_emitter.h"
|
||||
#include "util/file.h"
|
||||
#include "util/logger.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
bool JavaClientInterfaceCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
|
||||
{
|
||||
if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
|
||||
directory_ = GetFileParentPath(targetDirectory);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!File::CreateParentDir(directory_)) {
|
||||
Logger::E("JavaClientInterfaceCodeEmitter", "Create '%s' failed!", directory_.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void JavaClientInterfaceCodeEmitter::EmitCode()
|
||||
{
|
||||
if (mode_ == GenMode::IPC) {
|
||||
EmitInterfaceFile();
|
||||
}
|
||||
}
|
||||
|
||||
void JavaClientInterfaceCodeEmitter::EmitInterfaceFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.java", directory_.c_str(), FileName(interfaceName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
printf("%s/%s.java\n", directory_.c_str(), FileName(interfaceName_).c_str());
|
||||
EmitLicense(sb);
|
||||
EmitPackage(sb);
|
||||
sb.Append("\n");
|
||||
EmitInterfaceImports(sb);
|
||||
sb.Append("\n");
|
||||
EmitInterfaceDefinition(sb);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void JavaClientInterfaceCodeEmitter::EmitInterfaceImports(StringBuilder &sb) const
|
||||
{
|
||||
EmitInterfaceCorelibImports(sb);
|
||||
EmitInterfaceSelfDefinedTypeImports(sb);
|
||||
EmitInterfaceDBinderImports(sb);
|
||||
}
|
||||
|
||||
void JavaClientInterfaceCodeEmitter::EmitInterfaceCorelibImports(StringBuilder &sb) const
|
||||
{
|
||||
bool includeList = false;
|
||||
bool includeMap = false;
|
||||
|
||||
const AST::TypeStringMap &types = ast_->GetTypes();
|
||||
for (const auto &pair : types) {
|
||||
AutoPtr<ASTType> type = pair.second;
|
||||
switch (type->GetTypeKind()) {
|
||||
case TypeKind::TYPE_LIST: {
|
||||
if (!includeList) {
|
||||
sb.Append("import java.util.List;\n");
|
||||
includeList = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TypeKind::TYPE_MAP: {
|
||||
if (!includeMap) {
|
||||
sb.Append("import java.util.Map;\n");
|
||||
sb.Append("import java.util.HashMap;\n");
|
||||
includeMap = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JavaClientInterfaceCodeEmitter::EmitInterfaceDBinderImports(StringBuilder &sb) const
|
||||
{
|
||||
sb.Append("import ohos.rpc.IRemoteBroker;\n");
|
||||
sb.Append("import ohos.rpc.RemoteException;\n");
|
||||
}
|
||||
|
||||
void JavaClientInterfaceCodeEmitter::EmitInterfaceSelfDefinedTypeImports(StringBuilder &sb) const
|
||||
{
|
||||
for (const auto &importPair : ast_->GetImports()) {
|
||||
AutoPtr<AST> import = importPair.second;
|
||||
sb.AppendFormat("import %s;\n", import->GetFullName().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void JavaClientInterfaceCodeEmitter::EmitInterfaceDefinition(StringBuilder &sb)
|
||||
{
|
||||
sb.AppendFormat("public interface %s extends IRemoteBroker {\n", interface_->GetName().c_str());
|
||||
EmitInterfaceMethods(sb, TAB);
|
||||
sb.Append("}");
|
||||
}
|
||||
|
||||
void JavaClientInterfaceCodeEmitter::EmitInterfaceMethods(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
EmitInterfaceMethod(method, sb, prefix);
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void JavaClientInterfaceCodeEmitter::EmitInterfaceMethod(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
if (method->GetParameterNumber() == 0) {
|
||||
sb.Append(prefix).AppendFormat("int %s() throws RemoteException;\n", MethodName(method->GetName()).c_str());
|
||||
} else {
|
||||
StringBuilder paramStr;
|
||||
paramStr.Append(prefix).AppendFormat("int %s(", MethodName(method->GetName()).c_str());
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
EmitInterfaceMethodParameter(param, paramStr, "");
|
||||
if (i + 1 < method->GetParameterNumber()) {
|
||||
paramStr.Append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
paramStr.Append(") throws RemoteException;");
|
||||
sb.Append(SpecificationParam(paramStr, prefix + TAB));
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_JAVA_CLIENT_INTERFACE_CODE_EMITTER_H
|
||||
#define OHOS_IDL_JAVA_CLIENT_INTERFACE_CODE_EMITTER_H
|
||||
|
||||
#include "hdi_java_code_emitter.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
class JavaClientInterfaceCodeEmitter : public HDIJavaCodeEmitter {
|
||||
public:
|
||||
JavaClientInterfaceCodeEmitter() : HDIJavaCodeEmitter() {}
|
||||
|
||||
~JavaClientInterfaceCodeEmitter() override = default;
|
||||
|
||||
private:
|
||||
bool ResolveDirectory(const std::string &targetDirectory) override;
|
||||
|
||||
void EmitCode() override;
|
||||
|
||||
void EmitInterfaceFile();
|
||||
|
||||
void EmitInterfaceImports(StringBuilder &sb) const;
|
||||
|
||||
void EmitInterfaceCorelibImports(StringBuilder &sb) const;
|
||||
|
||||
void EmitInterfaceDBinderImports(StringBuilder &sb) const;
|
||||
|
||||
void EmitInterfaceSelfDefinedTypeImports(StringBuilder &sb) const;
|
||||
|
||||
void EmitInterfaceDefinition(StringBuilder &sb);
|
||||
|
||||
void EmitInterfaceMethods(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitInterfaceMethod(const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_JAVA_CLIENT_INTERFACE_CODE_EMITTER_H
|
262
idl_tool_2/codegen/HDI/java/java_client_proxy_code_emitter.cpp
Normal file
262
idl_tool_2/codegen/HDI/java/java_client_proxy_code_emitter.cpp
Normal file
@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "java_client_proxy_code_emitter.h"
|
||||
#include "util/logger.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
bool JavaClientProxyCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
|
||||
{
|
||||
if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
|
||||
directory_ = GetFileParentPath(targetDirectory);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!File::CreateParentDir(directory_)) {
|
||||
Logger::E("CppClientInterfaceCodeEmitter", "Create '%s' failed!", directory_.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void JavaClientProxyCodeEmitter::EmitCode()
|
||||
{
|
||||
if (mode_ == GenMode::IPC) {
|
||||
EmitProxyFile();
|
||||
}
|
||||
}
|
||||
|
||||
void JavaClientProxyCodeEmitter::EmitProxyFile()
|
||||
{
|
||||
std::string filePath =
|
||||
File::AdapterPath(StringHelper::Format("%s/%s.java", directory_.c_str(), FileName(proxyName_).c_str()));
|
||||
File file(filePath, File::write_);
|
||||
StringBuilder sb;
|
||||
|
||||
EmitLicense(sb);
|
||||
EmitPackage(sb);
|
||||
sb.Append("\n");
|
||||
EmitProxyImports(sb);
|
||||
sb.Append("\n");
|
||||
EmitProxyImpl(sb);
|
||||
|
||||
std::string data = sb.ToString();
|
||||
file.WriteData(data.c_str(), data.size());
|
||||
file.Flush();
|
||||
file.Close();
|
||||
}
|
||||
|
||||
void JavaClientProxyCodeEmitter::EmitProxyImports(StringBuilder &sb) const
|
||||
{
|
||||
EmitProxyCorelibImports(sb);
|
||||
EmitProxySelfDefinedTypeImports(sb);
|
||||
EmitProxyDBinderImports(sb);
|
||||
}
|
||||
|
||||
void JavaClientProxyCodeEmitter::EmitProxyCorelibImports(StringBuilder &sb) const
|
||||
{
|
||||
bool includeList = false;
|
||||
bool includeMap = false;
|
||||
const AST::TypeStringMap &types = ast_->GetTypes();
|
||||
for (const auto &pair : types) {
|
||||
AutoPtr<ASTType> type = pair.second;
|
||||
switch (type->GetTypeKind()) {
|
||||
case TypeKind::TYPE_LIST: {
|
||||
if (!includeList) {
|
||||
sb.Append("import java.util.List;\n");
|
||||
includeList = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TypeKind::TYPE_MAP: {
|
||||
if (!includeMap) {
|
||||
sb.Append("import java.util.Map;\n");
|
||||
sb.Append("import java.util.HashMap;\n");
|
||||
includeMap = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JavaClientProxyCodeEmitter::EmitProxySelfDefinedTypeImports(StringBuilder &sb) const
|
||||
{
|
||||
for (const auto &importPair : ast_->GetImports()) {
|
||||
AutoPtr<AST> import = importPair.second;
|
||||
sb.AppendFormat("import %s;\n", import->GetFullName().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void JavaClientProxyCodeEmitter::EmitProxyDBinderImports(StringBuilder &sb) const
|
||||
{
|
||||
sb.Append("import ohos.hiviewdfx.HiLog;\n");
|
||||
sb.Append("import ohos.hiviewdfx.HiLogLabel;\n");
|
||||
sb.Append("import ohos.rpc.IRemoteObject;\n");
|
||||
sb.Append("import ohos.rpc.RemoteException;\n");
|
||||
sb.Append("import ohos.rpc.MessageParcel;\n");
|
||||
sb.Append("import ohos.rpc.MessageOption;\n");
|
||||
}
|
||||
|
||||
void JavaClientProxyCodeEmitter::EmitProxyImpl(StringBuilder &sb)
|
||||
{
|
||||
sb.AppendFormat("public class %s implements %s {\n", proxyName_.c_str(), interfaceName_.c_str());
|
||||
EmitProxyConstants(sb, TAB);
|
||||
sb.Append("\n");
|
||||
sb.Append(TAB).AppendFormat(
|
||||
"private static final HiLogLabel TAG = new HiLogLabel(HiLog.LOG_CORE, 0xD001510, \"%s\");\n",
|
||||
interfaceFullName_.c_str());
|
||||
sb.Append(TAB).Append("private final IRemoteObject remote;\n");
|
||||
sb.Append(TAB).Append("private static final int ERR_OK = 0;\n");
|
||||
sb.Append("\n");
|
||||
EmitProxyConstructor(sb, TAB);
|
||||
sb.Append("\n");
|
||||
EmitProxyMethodImpls(sb, TAB);
|
||||
sb.Append("};");
|
||||
}
|
||||
|
||||
void JavaClientProxyCodeEmitter::EmitProxyConstants(StringBuilder &sb, const std::string &prefix)
|
||||
{
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"private static final std::string DESCRIPTOR = \"%s\";\n\n", interfaceFullName_.c_str());
|
||||
EmitInterfaceMethodCommands(sb, prefix);
|
||||
}
|
||||
|
||||
void JavaClientProxyCodeEmitter::EmitProxyConstructor(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).AppendFormat("public %s(IRemoteObject remote) {\n", proxyName_.c_str());
|
||||
sb.Append(prefix + TAB).Append("this.remote = remote;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
sb.Append("\n");
|
||||
sb.Append(prefix).AppendFormat("@Override\n");
|
||||
sb.Append(prefix).Append("public IRemoteObject asObject() {\n");
|
||||
sb.Append(prefix + TAB).Append("return remote;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void JavaClientProxyCodeEmitter::EmitProxyMethodImpls(StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
|
||||
EmitProxyMethodImpl(method, sb, prefix);
|
||||
sb.Append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void JavaClientProxyCodeEmitter::EmitProxyMethodImpl(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).Append("@Override\n");
|
||||
if (method->GetParameterNumber() == 0) {
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"public int %s() throws RemoteException ", MethodName(method->GetName()).c_str());
|
||||
} else {
|
||||
StringBuilder paramStr;
|
||||
paramStr.Append(prefix).AppendFormat("public int %s(", MethodName(method->GetName()).c_str());
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
EmitInterfaceMethodParameter(param, paramStr, "");
|
||||
if (i + 1 < method->GetParameterNumber()) {
|
||||
paramStr.Append(", ");
|
||||
}
|
||||
}
|
||||
paramStr.Append(") throws RemoteException");
|
||||
|
||||
sb.Append(SpecificationParam(paramStr, prefix + TAB));
|
||||
sb.Append("\n");
|
||||
}
|
||||
EmitProxyMethodBody(method, sb, prefix);
|
||||
}
|
||||
|
||||
void JavaClientProxyCodeEmitter::EmitProxyMethodBody(
|
||||
const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
sb.Append(prefix).Append("{\n");
|
||||
sb.Append(prefix + TAB).Append("MessageParcel data = MessageParcel.obtain();\n");
|
||||
sb.Append(prefix + TAB).Append("MessageParcel reply = MessageParcel.obtain();\n");
|
||||
sb.Append(prefix + TAB).AppendFormat("MessageOption option = new MessageOption(MessageOption.TF_SYNC);\n");
|
||||
sb.Append("\n");
|
||||
sb.Append(prefix).AppendFormat(" data.writeInterfaceToken(DESCRIPTOR);\n");
|
||||
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
EmitParamWriteVar(param, "data", sb, prefix + TAB);
|
||||
}
|
||||
sb.Append("\n");
|
||||
|
||||
sb.Append(prefix + TAB).Append("try {\n");
|
||||
sb.Append(prefix + TAB + TAB).AppendFormat("if (remote.sendRequest(COMMAND_%s, data, reply, option)) {\n",
|
||||
ConstantName(method->GetName()).c_str());
|
||||
sb.Append(prefix + TAB + TAB + TAB).Append("return 1;\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("}\n");
|
||||
sb.Append(prefix + TAB).Append(" reply.readException();\n");
|
||||
for (size_t i = 0; i < method->GetParameterNumber(); i++) {
|
||||
AutoPtr<ASTParameter> param = method->GetParameter(i);
|
||||
if (param->GetAttribute() == ASTParamAttr::PARAM_OUT) {
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
|
||||
typeEmitter->EmitJavaReadVar("reply", param->GetName(), sb, prefix + TAB + TAB);
|
||||
}
|
||||
}
|
||||
|
||||
sb.Append(prefix + TAB).Append("} finally {\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("data.reclaim();\n");
|
||||
sb.Append(prefix + TAB + TAB).Append("reply.reclaim();\n");
|
||||
sb.Append(prefix + TAB).Append("}\n");
|
||||
sb.Append(prefix + TAB).Append("return 0;\n");
|
||||
sb.Append(prefix).Append("}\n");
|
||||
}
|
||||
|
||||
void JavaClientProxyCodeEmitter::EmitParamWriteVar(const AutoPtr<ASTParameter> ¶m,
|
||||
const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
ASTParamAttr::ParamAttr attrAttr = param->GetAttribute();
|
||||
AutoPtr<ASTType> type = param->GetType();
|
||||
std::string name = param->GetName();
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
|
||||
if (attrAttr == ASTParamAttr::PARAM_IN) {
|
||||
typeEmitter->EmitJavaWriteVar(parcelName, name, sb, prefix);
|
||||
}
|
||||
if (attrAttr == ASTParamAttr::PARAM_OUT) {
|
||||
if (type->GetTypeKind() == TypeKind::TYPE_ARRAY) {
|
||||
typeEmitter->EmitJavaWriteVar(parcelName, name, sb, prefix, TypeMode::PARAM_OUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JavaClientProxyCodeEmitter::EmitLocalVariable(
|
||||
const AutoPtr<ASTParameter> ¶m, StringBuilder &sb, const std::string &prefix) const
|
||||
{
|
||||
AutoPtr<ASTType> type = param->GetType();
|
||||
AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(type);
|
||||
if (type->IsSequenceableType()) {
|
||||
sb.Append(prefix).AppendFormat("%s %s = new %s();\n", typeEmitter->EmitJavaType(TypeMode::NO_MODE).c_str(),
|
||||
param->GetName().c_str(), typeEmitter->EmitJavaType(TypeMode::NO_MODE).c_str());
|
||||
} else if (type->IsListType()) {
|
||||
sb.Append(prefix).AppendFormat("%s %s = new Array%s();\n", typeEmitter->EmitJavaType(TypeMode::NO_MODE).c_str(),
|
||||
param->GetName().c_str(), typeEmitter->EmitJavaType(TypeMode::NO_MODE).c_str());
|
||||
} else if (type->IsMapType()) {
|
||||
sb.Append(prefix).AppendFormat("%s %s = new Hash%s();\n", typeEmitter->EmitJavaType(TypeMode::NO_MODE).c_str(),
|
||||
param->GetName().c_str(), typeEmitter->EmitJavaType(TypeMode::NO_MODE).c_str());
|
||||
} else {
|
||||
sb.Append(prefix).AppendFormat(
|
||||
"%s %s;\n", typeEmitter->EmitJavaType(TypeMode::NO_MODE).c_str(), param->GetName().c_str());
|
||||
}
|
||||
}
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
71
idl_tool_2/codegen/HDI/java/java_client_proxy_code_emitter.h
Normal file
71
idl_tool_2/codegen/HDI/java/java_client_proxy_code_emitter.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_IDL_JAVA_CLIENT_PROXY_CODE_EMITTER_H
|
||||
#define OHOS_IDL_JAVA_CLIENT_PROXY_CODE_EMITTER_H
|
||||
|
||||
#include "hdi_java_code_emitter.h"
|
||||
#include "util/file.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Idl {
|
||||
class JavaClientProxyCodeEmitter : public HDIJavaCodeEmitter {
|
||||
public:
|
||||
JavaClientProxyCodeEmitter() : HDIJavaCodeEmitter() {}
|
||||
|
||||
~JavaClientProxyCodeEmitter() override = default;
|
||||
|
||||
private:
|
||||
bool ResolveDirectory(const std::string &targetDirectory) override;
|
||||
|
||||
void EmitCode() override;
|
||||
|
||||
void EmitProxyFile();
|
||||
|
||||
void EmitProxyImports(StringBuilder &sb) const;
|
||||
|
||||
void EmitProxyCorelibImports(StringBuilder &sb) const;
|
||||
|
||||
void EmitProxySelfDefinedTypeImports(StringBuilder &sb) const;
|
||||
|
||||
void EmitProxyDBinderImports(StringBuilder &sb) const;
|
||||
|
||||
void EmitProxyImpl(StringBuilder &sb);
|
||||
|
||||
void EmitProxyConstants(StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitProxyConstructor(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitProxyMethodImpls(StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitProxyMethodImpl(const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitProxyMethodBody(const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitReadOutArrayVariable(const std::string &parcelName, const std::string &name,
|
||||
const AutoPtr<ASTArrayType> &arrayType, StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitReadOutVariable(const std::string &parcelName, const std::string &name, const AutoPtr<ASTType> &type,
|
||||
StringBuilder &sb, const std::string &prefix);
|
||||
|
||||
void EmitLocalVariable(const AutoPtr<ASTParameter> ¶m, StringBuilder &sb, const std::string &prefix) const;
|
||||
|
||||
void EmitParamWriteVar(const AutoPtr<ASTParameter> ¶m,
|
||||
const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const;
|
||||
};
|
||||
} // namespace Idl
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // OHOS_IDL_JAVA_CLIENT_PROXY_CODE_EMITTER_H
|
Loading…
Reference in New Issue
Block a user