1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "StringType.h" 18 19 #include "HidlTypeAssertion.h" 20 21 #include <hidl-util/Formatter.h> 22 23 namespace android { 24 25 StringType::StringType(Scope* parent) : Type(parent) {} 26 27 bool StringType::isString() const { 28 return true; 29 } 30 31 bool StringType::deepCanCheckEquality(std::unordered_set<const Type*>* /* visited */) const { 32 return true; 33 } 34 35 std::string StringType::typeName() const { 36 return "string"; 37 } 38 39 std::string StringType::getCppType(StorageMode mode, 40 bool specifyNamespaces) const { 41 const std::string base = 42 std::string(specifyNamespaces ? "::android::hardware::" : "") 43 + "hidl_string"; 44 45 switch (mode) { 46 case StorageMode_Stack: 47 return base; 48 49 case StorageMode_Argument: 50 return "const " + base + "&"; 51 52 case StorageMode_Result: 53 return "const " + base + "*"; 54 } 55 } 56 57 std::string StringType::getJavaType(bool /* forInitializer */) const { 58 return "String"; 59 } 60 61 std::string StringType::getJavaSuffix() const { 62 return "String"; 63 } 64 65 std::string StringType::getVtsType() const { 66 return "TYPE_STRING"; 67 } 68 69 void StringType::emitReaderWriter( 70 Formatter &out, 71 const std::string &name, 72 const std::string &parcelObj, 73 bool parcelObjIsPointer, 74 bool isReader, 75 ErrorMode mode) const { 76 const std::string parentName = "_hidl_" + name + "_parent"; 77 out << "size_t " << parentName << ";\n\n"; 78 79 const std::string parcelObjDeref = 80 parcelObj + (parcelObjIsPointer ? "->" : "."); 81 82 if (isReader) { 83 out << "_hidl_err = " 84 << parcelObjDeref 85 << "readBuffer(" 86 << "sizeof(*" 87 << name 88 << "), &" 89 << parentName 90 << ", " 91 << " reinterpret_cast<const void **>(" 92 << "&" << name 93 << "));\n\n"; 94 95 handleError(out, mode); 96 } else { 97 out << "_hidl_err = " 98 << parcelObjDeref 99 << "writeBuffer(&" 100 << name 101 << ", sizeof(" 102 << name 103 << "), &" 104 << parentName 105 << ");\n"; 106 107 handleError(out, mode); 108 } 109 110 emitReaderWriterEmbedded( 111 out, 112 0 /* depth */, 113 name, 114 name /* sanitizedName */, 115 isReader /* nameIsPointer */, 116 parcelObj, 117 parcelObjIsPointer, 118 isReader, 119 mode, 120 parentName, 121 "0 /* parentOffset */"); 122 } 123 124 void StringType::emitReaderWriterEmbedded( 125 Formatter &out, 126 size_t /* depth */, 127 const std::string &name, 128 const std::string & /*sanitizedName*/, 129 bool nameIsPointer, 130 const std::string &parcelObj, 131 bool parcelObjIsPointer, 132 bool isReader, 133 ErrorMode mode, 134 const std::string &parentName, 135 const std::string &offsetText) const { 136 emitReaderWriterEmbeddedForTypeName( 137 out, 138 name, 139 nameIsPointer, 140 parcelObj, 141 parcelObjIsPointer, 142 isReader, 143 mode, 144 parentName, 145 offsetText, 146 "::android::hardware::hidl_string", 147 "" /* childName */, 148 "::android::hardware"); 149 } 150 151 void StringType::emitJavaFieldInitializer( 152 Formatter &out, const std::string &fieldName) const { 153 out << "String " 154 << fieldName 155 << " = new String();\n"; 156 } 157 158 void StringType::emitJavaFieldReaderWriter( 159 Formatter &out, 160 size_t /* depth */, 161 const std::string &parcelName, 162 const std::string &blobName, 163 const std::string &fieldName, 164 const std::string &offset, 165 bool isReader) const { 166 if (isReader) { 167 out << fieldName 168 << " = " 169 << blobName 170 << ".getString(" 171 << offset 172 << ");\n"; 173 174 out << "\n" 175 << parcelName 176 << ".readEmbeddedBuffer(\n"; 177 178 out.indent(); 179 out.indent(); 180 181 // hidl_string's embedded buffer is never null(able), because it defaults to a 182 // buffer containing an empty string. 183 out << fieldName << ".getBytes().length + 1,\n" 184 << blobName 185 << ".handle(),\n" 186 << offset 187 << " + 0 /* offsetof(hidl_string, mBuffer) */," 188 << "false /* nullable */);\n\n"; 189 190 out.unindent(); 191 out.unindent(); 192 193 return; 194 } 195 196 out << blobName 197 << ".putString(" 198 << offset 199 << ", " 200 << fieldName 201 << ");\n"; 202 } 203 204 bool StringType::needsEmbeddedReadWrite() const { 205 return true; 206 } 207 208 bool StringType::resultNeedsDeref() const { 209 return true; 210 } 211 212 void StringType::emitVtsTypeDeclarations(Formatter& out) const { 213 out << "type: " << getVtsType() << "\n"; 214 } 215 216 static HidlTypeAssertion assertion("hidl_string", 16 /* size */); 217 void StringType::getAlignmentAndSize(size_t *align, size_t *size) const { 218 *align = 8; // hidl_string 219 *size = assertion.size(); 220 } 221 222 } // namespace android 223 224