ArrayType.cpp revision 5158db484e5ab302368f191d75d5b1334c270e52
1#include "ArrayType.h"
2
3#include "Formatter.h"
4
5#include <android-base/logging.h>
6
7namespace android {
8
9ArrayType::ArrayType(Type *elementType, const char *dimension)
10    : mElementType(elementType),
11      mDimension(dimension) {
12}
13
14std::string ArrayType::getCppType(StorageMode mode, std::string *extra) const {
15    const std::string base = mElementType->getCppType(extra);
16
17    CHECK(extra->empty());
18
19    *extra = "[" + mDimension + "]";
20
21    switch (mode) {
22        case StorageMode_Stack:
23            return base;
24
25        case StorageMode_Argument:
26            return "const " + base;
27
28        case StorageMode_Result:
29        {
30            extra->clear();
31            return "const " + base + "*";
32        }
33    }
34}
35
36std::string ArrayType::getJavaType() const {
37    return mElementType->getJavaType() + "[]";
38}
39
40void ArrayType::emitReaderWriter(
41        Formatter &out,
42        const std::string &name,
43        const std::string &parcelObj,
44        bool parcelObjIsPointer,
45        bool isReader,
46        ErrorMode mode) const {
47    std::string baseExtra;
48    std::string baseType = mElementType->getCppType(&baseExtra);
49
50    const std::string parentName = "_hidl_" + name + "_parent";
51
52    out << "size_t " << parentName << ";\n\n";
53
54    const std::string parcelObjDeref =
55        parcelObj + (parcelObjIsPointer ? "->" : ".");
56
57    if (isReader) {
58        out << name
59            << " = (const "
60            << baseType
61            << " *)"
62            << parcelObjDeref
63            << "readBuffer(&"
64            << parentName
65            << ");\n\n";
66
67        out << "if (" << name << " == nullptr) {\n";
68
69        out.indent();
70
71        out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
72        handleError2(out, mode);
73
74        out.unindent();
75        out << "}\n\n";
76    } else {
77        out << "_hidl_err = "
78            << parcelObjDeref
79            << "writeBuffer("
80            << name
81            << ", "
82            << mDimension
83            << " * sizeof("
84            << baseType
85            << "), &"
86            << parentName
87            << ");\n";
88
89        handleError(out, mode);
90    }
91
92    emitReaderWriterEmbedded(
93            out,
94            name,
95            isReader /* nameIsPointer */,
96            parcelObj,
97            parcelObjIsPointer,
98            isReader,
99            mode,
100            parentName,
101            "0 /* parentOffset */");
102}
103
104void ArrayType::emitReaderWriterEmbedded(
105        Formatter &out,
106        const std::string &name,
107        bool nameIsPointer,
108        const std::string &parcelObj,
109        bool parcelObjIsPointer,
110        bool isReader,
111        ErrorMode mode,
112        const std::string &parentName,
113        const std::string &offsetText) const {
114    if (!mElementType->needsEmbeddedReadWrite()) {
115        return;
116    }
117
118    const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
119
120    std::string baseExtra;
121    std::string baseType = mElementType->getCppType(&baseExtra);
122
123    out << "for (size_t _hidl_index = 0; _hidl_index < "
124        << mDimension
125        << "; ++_hidl_index) {\n";
126
127    out.indent();
128
129    mElementType->emitReaderWriterEmbedded(
130            out,
131            name + "[_hidl_index]",
132            false /* nameIsPointer */,
133            parcelObj,
134            parcelObjIsPointer,
135            isReader,
136            mode,
137            parentName,
138            offsetText + " + _hidl_index * sizeof(" + baseType + ")");
139
140    out.unindent();
141
142    out << "}\n\n";
143}
144
145bool ArrayType::needsEmbeddedReadWrite() const {
146    return mElementType->needsEmbeddedReadWrite();
147}
148
149void ArrayType::emitJavaReaderWriter(
150        Formatter &out,
151        const std::string &parcelObj,
152        const std::string &argName,
153        bool isReader) const {
154    emitJavaReaderWriterWithSuffix(
155            out,
156            parcelObj,
157            argName,
158            isReader,
159            mElementType->getJavaSuffix() + "Array",
160            mDimension);
161}
162
163status_t ArrayType::emitVtsTypeDeclarations(Formatter &out) const {
164    out << "type: TYPE_ARRAY\n" << "vector_value: {\n";
165    out.indent();
166    out << "size: " << mDimension;
167    status_t err = mElementType->emitVtsTypeDeclarations(out);
168    if (err != OK) {
169        return err;
170    }
171    out.unindent();
172    out << "}\n";
173    return OK;
174}
175
176}  // namespace android
177
178