/* * Copyright (C) 2016 The Android Open Source Project * * 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 "MemoryType.h" #include "HidlTypeAssertion.h" #include #include namespace android { MemoryType::MemoryType(Scope* parent) : Type(parent, "memory") {} std::string MemoryType::getCppType(StorageMode mode, bool specifyNamespaces) const { const std::string base = std::string(specifyNamespaces ? "::android::hardware::" : "") + "hidl_memory"; switch (mode) { case StorageMode_Stack: return base; case StorageMode_Argument: return "const " + base + "&"; case StorageMode_Result: return "const " + base + "*"; } } std::string MemoryType::typeName() const { return "memory"; } std::string MemoryType::getVtsType() const { return "TYPE_HIDL_MEMORY"; } std::string MemoryType::getJavaType(bool /* forInitializer */) const { return "android.os.HidlMemory"; } std::string MemoryType::getJavaSuffix() const { return "HidlMemory"; } void MemoryType::emitJavaFieldInitializer( Formatter &out, const std::string &fieldName) const { const std::string fieldDeclaration = getJavaType(false) + " " + fieldName; emitJavaFieldDefaultInitialValue(out, fieldDeclaration); } void MemoryType::emitJavaFieldDefaultInitialValue( Formatter &out, const std::string &declaredFieldName) const { out << declaredFieldName << " = null;\n"; } void MemoryType::emitJavaFieldReaderWriter(Formatter& out, size_t /* depth */, const std::string& parcelName, const std::string& blobName, const std::string& fieldName, const std::string& offset, bool isReader) const { if (isReader) { out << "try {\n"; out.indent(); out << fieldName << " = " << parcelName << ".readEmbeddedHidlMemory(\n"; out << blobName << ".getFieldHandle(" << offset << "),\n" << blobName << ".handle(),\n" << offset << ").dup();\n"; out.unindent(); out << "} catch (java.io.IOException e) {\n"; out.indent(); out << "throw new RuntimeException(e);\n"; out.unindent(); out << "}\n"; return; } out << blobName << ".putHidlMemory(" << offset << ", " << fieldName << ");\n"; } void MemoryType::emitJavaReaderWriter(Formatter& out, const std::string& parcelObj, const std::string& argName, bool isReader) const { if (isReader) { // The weird-looking lambda code below is intended to replace an // IOException with a RuntimeException within an expression context. out << "((java.util.function.Function)" " _parcel -> {\n"; out.indent(); out << "try {\n"; out.indent(); out << "return _parcel.readHidlMemory().dup();\n"; out.unindent(); out << "} catch (java.io.IOException e) {\n"; out.indent(); out << "throw new RuntimeException(e);\n"; out.unindent(); out << "}\n"; out.unindent(); out << "}).apply(" << parcelObj << ");\n"; } else { out << parcelObj << ".writeHidlMemory(" << argName << ");\n"; } } void MemoryType::emitReaderWriter( Formatter &out, const std::string &name, const std::string &parcelObj, bool parcelObjIsPointer, bool isReader, ErrorMode mode) const { const std::string parentName = "_hidl_" + name + "_parent"; out << "size_t " << parentName << ";\n\n"; const std::string parcelObjDeref = parcelObj + (parcelObjIsPointer ? "->" : "."); if (isReader) { out << "_hidl_err = " << parcelObjDeref << "readBuffer(" << "sizeof(*" << name << "), &" << parentName << ", " << " reinterpret_cast(" << "&" << name << "));\n\n"; handleError(out, mode); } else { out << "_hidl_err = " << parcelObjDeref << "writeBuffer(&" << name << ", sizeof(" << name << "), &" << parentName << ");\n"; handleError(out, mode); } emitReaderWriterEmbedded( out, 0 /* depth */, name, name /* sanitizedName */, isReader /* nameIsPointer */, parcelObj, parcelObjIsPointer, isReader, mode, parentName, "0 /* parentOffset */"); } void MemoryType::emitReaderWriterEmbedded( Formatter &out, size_t /* depth */, const std::string &name, const std::string & /*sanitizedName*/, bool nameIsPointer, const std::string &parcelObj, bool parcelObjIsPointer, bool isReader, ErrorMode mode, const std::string &parentName, const std::string &offsetText) const { emitReaderWriterEmbeddedForTypeName( out, name, nameIsPointer, parcelObj, parcelObjIsPointer, isReader, mode, parentName, offsetText, "::android::hardware::hidl_memory", "" /* childName */, "::android::hardware"); } bool MemoryType::needsEmbeddedReadWrite() const { return true; } bool MemoryType::resultNeedsDeref() const { return true; } bool MemoryType::isMemory() const { return true; } bool MemoryType::deepIsJavaCompatible(std::unordered_set* /* visited */) const { return true; } static HidlTypeAssertion assertion("hidl_memory", 40 /* size */); void MemoryType::getAlignmentAndSize(size_t *align, size_t *size) const { *align = 8; // hidl_memory *size = assertion.size(); } void MemoryType::emitVtsTypeDeclarations(Formatter& out) const { out << "type: " << getVtsType() << "\n"; } } // namespace android