/* * 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 "metadata/metadata_reader.h" #include "metadata/metadata_serializer.h" #include "util/file.h" #include "util/logger.h" namespace OHOS { namespace Idl { std::string MetadataReader::tag_ = "MetadataReader"; std::shared_ptr<MetaComponent> MetadataReader::ReadMetadataFromFile(const std::string& filePath) { File file(filePath, File::READ); if (!file.IsValid()) { Logger::E(tag_.c_str(), "Open \"%s\" file failed.", filePath.c_str()); return nullptr; } if (!file.Reset()) { Logger::E(tag_.c_str(), "Reset \"%s\" file failed.", filePath.c_str()); return nullptr; } MetaComponent header; if (!file.ReadData((void*)&header, sizeof(MetaComponent))) { Logger::E(tag_.c_str(), "Read \"%s\" file failed.", filePath.c_str()); return nullptr; } if (header.magic_ != METADATA_MAGIC_NUMBER || header.size_ < 0) { Logger::E(tag_.c_str(), "The metadata in \"%s\" file is bad.", filePath.c_str()); return nullptr; } if (!file.Reset()) { Logger::E(tag_.c_str(), "Reset \"%s\" file failed.", filePath.c_str()); return nullptr; } void* data = malloc(header.size_); if (data == nullptr) { Logger::E(tag_.c_str(), "Malloc metadata failed."); return nullptr; } if (!file.ReadData(data, header.size_)) { Logger::E(tag_.c_str(), "Read \"%s\" file failed.", filePath.c_str()); free(data); return nullptr; } std::shared_ptr<MetaComponent> metadata(reinterpret_cast<MetaComponent *>(data), [](MetaComponent* p) { free(p); }); MetadataSerializer serializer((uintptr_t)data); serializer.Deserialize(); return metadata; } std::unordered_map<std::string, AutoPtr<AST>> MetadataReader::ReadMetadataToAst() { std::unordered_map<std::string, AutoPtr<AST>> allAsts; ast_ = new AST(); for (int i = 0; i < metaComponent_->sequenceableNumber_; i++) { ReadMetaSequenceable(metaComponent_->sequenceables_[i]); } for (int i = 0; i < metaComponent_->interfaceNumber_; i++) { ReadMetaInterface(metaComponent_->interfaces_[i]); } ast_->SetFullName(std::string(reinterpret_cast<char*>(metaComponent_->name_))); ast_->SetAStFileType(ASTFileType::AST_IFACE); allAsts[std::string(reinterpret_cast<char*>(metaComponent_->name_))] = ast_; return allAsts; } void MetadataReader::ReadMetaSequenceable(MetaSequenceable* mp) { AutoPtr<ASTSequenceableType> seqType = new ASTSequenceableType(); seqType->SetName(std::string(reinterpret_cast<char*>(mp->name_))); seqType->SetNamespace(ast_->ParseNamespace(std::string(reinterpret_cast<char*>(mp->namespace_)))); AutoPtr<AST> seqAst = new AST(); seqAst->SetFullName(seqType->GetFullName()); seqAst->AddSequenceableDef(seqType); seqAst->SetAStFileType(ASTFileType::AST_SEQUENCEABLE); ast_->AddImport(seqAst); ast_->AddSequenceableDef(seqType); } void MetadataReader::ReadMetaInterface(MetaInterface* mi) { AutoPtr<ASTInterfaceType> interface = new ASTInterfaceType(); AutoPtr<ASTAttr> infAttr = new ASTAttr(); if (mi->properties_ == INTERFACE_PROPERTY_ONEWAY) { infAttr->SetValue(ASTAttr::ONEWAY); } interface->SetAttribute(infAttr); if (!mi->external_) { interface->SetLicense(std::string(reinterpret_cast<char*>(mi->license_))); ast_->SetLicense(std::string(reinterpret_cast<char*>(mi->license_))); } interface->SetName(std::string(reinterpret_cast<char*>(mi->name_))); interface->SetNamespace(ast_->ParseNamespace(std::string(reinterpret_cast<char*>(mi->namespace_)))); interface->SetExternal(mi->external_); ast_->AddInterfaceDef(interface); for (int i = 0; i < mi->methodNumber_; i++) { ReadMetaMethod(interface, mi->methods_[i]); } } void MetadataReader::ReadMetaMethod(AutoPtr<ASTInterfaceType>& interface, MetaMethod* mm) { AutoPtr<ASTMethod> method = new ASTMethod(); AutoPtr<ASTAttr> methodAttr = new ASTAttr(); if (mm->properties_ == METHOD_PROPERTY_ONEWAY) { methodAttr->SetValue(ASTAttr::ONEWAY); } method->SetAttribute(methodAttr); MetaType* type = metaComponent_->types_[mm->returnTypeIndex_]; method->SetReturnType(ReadMetaType(type)); method->SetName(std::string(reinterpret_cast<char*>((mm->name_)))); for (int i = 0; i < mm->parameterNumber_; i++) { ReadMetaParam(method, mm->parameters_[i]); } interface->AddMethod(method); } void MetadataReader::ReadMetaParam(AutoPtr<ASTMethod>& method, MetaParameter* mp) { AutoPtr<ASTParamAttr> attr = new ASTParamAttr(ASTParamAttr::PARAM_NONE); if ((mp->attributes_ & ATTR_IN) == ATTR_IN) { attr->value_ |= ASTParamAttr::PARAM_IN; } if ((mp->attributes_ & ATTR_OUT) == ATTR_OUT) { attr->value_ |= ASTParamAttr::PARAM_OUT; } MetaType* type = metaComponent_->types_[mp->typeIndex_]; AutoPtr<ASTParameter> param = new ASTParameter(std::string(reinterpret_cast<char*>((mp->name_))), attr, ReadMetaType(type)); method->AddParameter(param); } AutoPtr<ASTType> MetadataReader::ReadMetaType(MetaType* type) { std::string typeName = MetaTypeName(type); AutoPtr<ASTType> astType = ast_->FindType(typeName); switch (type->kind_) { case MetaTypeKind::List: if (astType == nullptr) { MetaType* elementMt = metaComponent_->types_[type->nestedTypeIndexes_[0]]; AutoPtr<ASTListType> listType = new ASTListType(); listType->SetElementType(ReadMetaType(elementMt)); astType = listType.Get(); } break; case MetaTypeKind::Map: if (astType == nullptr) { MetaType* keyMt = metaComponent_->types_[type->nestedTypeIndexes_[0]]; MetaType* valueMt = metaComponent_->types_[type->nestedTypeIndexes_[1]]; AutoPtr<ASTMapType> mapType = new ASTMapType(); mapType->SetKeyType(ReadMetaType(keyMt)); mapType->SetValueType(ReadMetaType(valueMt)); astType = mapType.Get(); } break; case MetaTypeKind::Array: if (astType == nullptr) { MetaType* elementMt = metaComponent_->types_[type->nestedTypeIndexes_[0]]; AutoPtr<ASTArrayType> arrayType = new ASTArrayType(); arrayType->SetElementType(ReadMetaType(elementMt)); astType = arrayType.Get(); } break; default: break; } ast_->AddType(astType); return astType; } std::string MetadataReader::MetaTypeName(MetaType* mt) { switch (mt->kind_) { case MetaTypeKind::Char: return "char"; case MetaTypeKind::Boolean: return "boolean"; case MetaTypeKind::Byte: return "byte"; case MetaTypeKind::Short: return "short"; case MetaTypeKind::Integer: return "int"; case MetaTypeKind::Long: return "long"; case MetaTypeKind::Float: return "float"; case MetaTypeKind::Double: return "double"; case MetaTypeKind::String: return "String"; case MetaTypeKind::Void: return "void"; case MetaTypeKind::Sequenceable: { MetaSequenceable* mp = metaComponent_->sequenceables_[mt->index_]; return reinterpret_cast<char*>(mp->name_); } case MetaTypeKind::Interface: { MetaInterface* mi = metaComponent_->interfaces_[mt->index_]; return reinterpret_cast<char*>(mi->name_); } case MetaTypeKind::List: { MetaType* elementMt = metaComponent_->types_[mt->nestedTypeIndexes_[0]]; return "List<" + MetaTypeName(elementMt) + ">"; } case MetaTypeKind::Map: { MetaType* keyMt = metaComponent_->types_[mt->nestedTypeIndexes_[0]]; MetaType* valueMt = metaComponent_->types_[mt->nestedTypeIndexes_[1]]; return "Map<" + MetaTypeName(keyMt) + ", " + MetaTypeName(valueMt) + ">"; } case MetaTypeKind::Array: { MetaType* elementMt = metaComponent_->types_[mt->nestedTypeIndexes_[0]]; return MetaTypeName(elementMt) + "[]"; } case MetaTypeKind::Unknown: default: printf("Unknown %d\n", mt->index_); return "unknown"; } } } // namespace Idl } // namespace OHOS