11aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber/*
21aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Copyright (C) 2016 The Android Open Source Project
31aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *
41aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
51aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * you may not use this file except in compliance with the License.
61aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * You may obtain a copy of the License at
71aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *
81aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
91aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *
101aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Unless required by applicable law or agreed to in writing, software
111aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
121aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * See the License for the specific language governing permissions and
141aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * limitations under the License.
151aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber */
161aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber
17c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber#include "StringType.h"
18c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
196755e9d6232f8c9451b5d57cfd36be35eeeb16e1Andreas Huber#include "HidlTypeAssertion.h"
206755e9d6232f8c9451b5d57cfd36be35eeeb16e1Andreas Huber
21a72e0d2be173cebf62f728b9d215808bd862f219Iliyan Malchev#include <hidl-util/Formatter.h>
22c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
23c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Hubernamespace android {
24c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
2563f399021d053453704d41845d4ebcc06fe01738Timur IskhakovStringType::StringType(Scope* parent) : Type(parent) {}
26c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
27abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hongbool StringType::isString() const {
28abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong    return true;
29abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong}
30abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong
315dc72fe4f6f1d2c03c75307a9bd80f055f752ed3Timur Iskhakovbool StringType::deepCanCheckEquality(std::unordered_set<const Type*>* /* visited */) const {
32c6752dcea3b5dae1e99960b5beb6af394280b393Yifan Hong    return true;
33c6752dcea3b5dae1e99960b5beb6af394280b393Yifan Hong}
34c6752dcea3b5dae1e99960b5beb6af394280b393Yifan Hong
350ecc7b8aca24a5618512610bb6371bdb91b5fdc2Steven Morelandstd::string StringType::typeName() const {
360ecc7b8aca24a5618512610bb6371bdb91b5fdc2Steven Moreland    return "string";
370ecc7b8aca24a5618512610bb6371bdb91b5fdc2Steven Moreland}
380ecc7b8aca24a5618512610bb6371bdb91b5fdc2Steven Moreland
39979e099f1163ff75beed5776cd01fb409b90a0cdSteven Morelandstd::string StringType::getCppType(StorageMode mode,
40979e099f1163ff75beed5776cd01fb409b90a0cdSteven Moreland                                   bool specifyNamespaces) const {
41979e099f1163ff75beed5776cd01fb409b90a0cdSteven Moreland    const std::string base =
42979e099f1163ff75beed5776cd01fb409b90a0cdSteven Moreland          std::string(specifyNamespaces ? "::android::hardware::" : "")
43979e099f1163ff75beed5776cd01fb409b90a0cdSteven Moreland        + "hidl_string";
44881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
45881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    switch (mode) {
46881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        case StorageMode_Stack:
47881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            return base;
48881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
49881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        case StorageMode_Argument:
50881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            return "const " + base + "&";
51881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
52881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        case StorageMode_Result:
53881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            return "const " + base + "*";
54881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    }
55881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
56881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
574ed1347cd29e6e07acad368891bb03078c798abaYifan Hongstd::string StringType::getJavaType(bool /* forInitializer */) const {
582831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    return "String";
592831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
602831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
612831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huberstd::string StringType::getJavaSuffix() const {
622831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    return "String";
632831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
642831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
65c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhangstd::string StringType::getVtsType() const {
66c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    return "TYPE_STRING";
67c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang}
68c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang
69881227d860c59471eee31d39946e96ce2daa35d6Andreas Hubervoid StringType::emitReaderWriter(
70881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        Formatter &out,
71881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &name,
72881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &parcelObj,
73881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool parcelObjIsPointer,
74881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool isReader,
75881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        ErrorMode mode) const {
76549e2598843dcc092a6049bbd9e209c249b1b11aIliyan Malchev    const std::string parentName = "_hidl_" + name + "_parent";
77881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out << "size_t " << parentName << ";\n\n";
78881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
79881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    const std::string parcelObjDeref =
80881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        parcelObj + (parcelObjIsPointer ? "->" : ".");
81881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
82881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    if (isReader) {
836a082c63904f274c45d5eede313e0ef77ec70f86Martijn Coenen        out << "_hidl_err = "
84881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << parcelObjDeref
85b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen            << "readBuffer("
86b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen            << "sizeof(*"
87b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen            << name
88b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen            << "), &"
89881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << parentName
906a082c63904f274c45d5eede313e0ef77ec70f86Martijn Coenen            << ", "
916a082c63904f274c45d5eede313e0ef77ec70f86Martijn Coenen            << " reinterpret_cast<const void **>("
926a082c63904f274c45d5eede313e0ef77ec70f86Martijn Coenen            << "&" << name
936a082c63904f274c45d5eede313e0ef77ec70f86Martijn Coenen            << "));\n\n";
94881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
956a082c63904f274c45d5eede313e0ef77ec70f86Martijn Coenen        handleError(out, mode);
96881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    } else {
97549e2598843dcc092a6049bbd9e209c249b1b11aIliyan Malchev        out << "_hidl_err = "
98881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << parcelObjDeref
99881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << "writeBuffer(&"
100881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << name
101881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << ", sizeof("
102881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << name
103881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << "), &"
104881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << parentName
105881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            << ");\n";
106881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
107881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        handleError(out, mode);
108881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    }
109881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
110881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    emitReaderWriterEmbedded(
111881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            out,
112f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber            0 /* depth */,
113881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            name,
114be2a3737675b83dd61b52c11f0d7549fa1276739Yifan Hong            name /* sanitizedName */,
115881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            isReader /* nameIsPointer */,
116881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            parcelObj,
117881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            parcelObjIsPointer,
118881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            isReader,
119881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            mode,
120881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            parentName,
121881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            "0 /* parentOffset */");
122881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
123881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
124881227d860c59471eee31d39946e96ce2daa35d6Andreas Hubervoid StringType::emitReaderWriterEmbedded(
125881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        Formatter &out,
126f9d49f1468bd65595f6f0ae5f4d7300f4e95edf8Andreas Huber        size_t /* depth */,
127881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &name,
128be2a3737675b83dd61b52c11f0d7549fa1276739Yifan Hong        const std::string & /*sanitizedName*/,
129881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool nameIsPointer,
130881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &parcelObj,
131881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool parcelObjIsPointer,
132881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool isReader,
133881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        ErrorMode mode,
134881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &parentName,
135881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &offsetText) const {
136881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    emitReaderWriterEmbeddedForTypeName(
137881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            out,
138881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            name,
139881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            nameIsPointer,
140881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            parcelObj,
141881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            parcelObjIsPointer,
142881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            isReader,
143881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            mode,
144881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            parentName,
145881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber            offsetText,
1468a82ff7ce6b5c0288b5239e25e1cbd1f5d8e3d27Andreas Huber            "::android::hardware::hidl_string",
147244e82d34bf0ef5d8d5b0730a9dea3e3fc4de7c5Yifan Hong            "" /* childName */,
148244e82d34bf0ef5d8d5b0730a9dea3e3fc4de7c5Yifan Hong            "::android::hardware");
149881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
150881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
15185eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid StringType::emitJavaFieldInitializer(
15285eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        Formatter &out, const std::string &fieldName) const {
15385eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    out << "String "
15485eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        << fieldName
15585eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        << " = new String();\n";
15685eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
15785eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
15885eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid StringType::emitJavaFieldReaderWriter(
15985eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        Formatter &out,
1604c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber        size_t /* depth */,
161709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        const std::string &parcelName,
16285eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &blobName,
16385eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &fieldName,
16485eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &offset,
16585eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        bool isReader) const {
16685eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    if (isReader) {
167b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen        out << fieldName
168b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen            << " = "
169b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen            << blobName
170b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen            << ".getString("
171b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen            << offset
172b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen            << ");\n";
173b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen
174709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        out << "\n"
175709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            << parcelName
176709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            << ".readEmbeddedBuffer(\n";
17785eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
17885eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        out.indent();
17985eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        out.indent();
18085eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
181011bb06ee0a4c4fa77dec7677e8c1ee41bb68121Martijn Coenen        // hidl_string's embedded buffer is never null(able), because it defaults to a
182011bb06ee0a4c4fa77dec7677e8c1ee41bb68121Martijn Coenen        // buffer containing an empty string.
18360aae9fa673ed4e0806c0bae810d024cfcd9c335Martijn Coenen        out << fieldName << ".getBytes().length + 1,\n"
184b2a861cf36ba30b0365d42b33fca0188d543c73cMartijn Coenen            << blobName
18585eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber            << ".handle(),\n"
18685eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber            << offset
187011bb06ee0a4c4fa77dec7677e8c1ee41bb68121Martijn Coenen            << " + 0 /* offsetof(hidl_string, mBuffer) */,"
188011bb06ee0a4c4fa77dec7677e8c1ee41bb68121Martijn Coenen            << "false /* nullable */);\n\n";
18985eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
19085eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        out.unindent();
19185eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        out.unindent();
19285eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
19385eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        return;
19485eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    }
19585eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
19685eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    out << blobName
19785eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        << ".putString("
19885eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        << offset
19985eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        << ", "
20085eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        << fieldName
20185eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        << ");\n";
20285eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
20385eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
204881227d860c59471eee31d39946e96ce2daa35d6Andreas Huberbool StringType::needsEmbeddedReadWrite() const {
205881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    return true;
206881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
207881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
208881227d860c59471eee31d39946e96ce2daa35d6Andreas Huberbool StringType::resultNeedsDeref() const {
209881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    return true;
210881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
211881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
212368e46077eb9fbe52242e037a5b9de91693fe70fSteven Morelandvoid StringType::emitVtsTypeDeclarations(Formatter& out) const {
213ae83dcd90dd6ab0aa0a8950fc79e88cfccdf5a89Zhuoyao Zhang    out << "type: " << getVtsType() << "\n";
2145158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
2155158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
2166755e9d6232f8c9451b5d57cfd36be35eeeb16e1Andreas Huberstatic HidlTypeAssertion assertion("hidl_string", 16 /* size */);
21785eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid StringType::getAlignmentAndSize(size_t *align, size_t *size) const {
21885eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    *align = 8;  // hidl_string
2196755e9d6232f8c9451b5d57cfd36be35eeeb16e1Andreas Huber    *size = assertion.size();
22085eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
22185eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
222c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber}  // namespace android
223c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
224