blob: 7feb9fb4c4ffb4eea40fcb82fb1a28e23f05cb2e [file] [log] [blame]
Andreas Huberc9410c72016-07-28 12:18:40 -07001#include "ArrayType.h"
2
3#include "Formatter.h"
4
Andreas Huber881227d2016-08-02 14:20:21 -07005#include <android-base/logging.h>
6
Andreas Huberc9410c72016-07-28 12:18:40 -07007namespace android {
8
9ArrayType::ArrayType(Type *elementType, const char *dimension)
10 : mElementType(elementType),
11 mDimension(dimension) {
12}
13
14void ArrayType::dump(Formatter &out) const {
15 mElementType->dump(out);
16 out << "[" << mDimension << "]";
17}
18
Andreas Huber881227d2016-08-02 14:20:21 -070019std::string ArrayType::getCppType(StorageMode mode, std::string *extra) const {
20 const std::string base = mElementType->getCppType(extra);
21
22 CHECK(extra->empty());
23
24 *extra = "[" + mDimension + "]";
25
26 switch (mode) {
27 case StorageMode_Stack:
28 return base;
29
30 case StorageMode_Argument:
31 return "const " + base;
32
33 case StorageMode_Result:
34 {
35 extra->clear();
36 return "const " + base + "*";
37 }
38 }
39}
40
41void ArrayType::emitReaderWriter(
42 Formatter &out,
43 const std::string &name,
44 const std::string &parcelObj,
45 bool parcelObjIsPointer,
46 bool isReader,
47 ErrorMode mode) const {
48 std::string baseExtra;
49 std::string baseType = mElementType->getCppType(&baseExtra);
50
51 const std::string parentName = "_aidl_" + name + "_parent";
52
53 out << "size_t " << parentName << ";\n\n";
54
55 const std::string parcelObjDeref =
56 parcelObj + (parcelObjIsPointer ? "->" : ".");
57
58 if (isReader) {
59 out << name
60 << " = (const "
61 << baseType
62 << " *)"
63 << parcelObjDeref
64 << "readBuffer(&"
65 << parentName
66 << ");\n\n";
67
68 out << "if (" << name << " == nullptr) {\n";
69
70 out.indent();
71
72 out << "_aidl_err = ::android::UNKNOWN_ERROR;\n";
73 handleError2(out, mode);
74
75 out.unindent();
76 out << "}\n\n";
77 } else {
78 out << "_aidl_err = "
79 << parcelObjDeref
80 << "writeBuffer("
81 << name
82 << ", "
83 << mDimension
84 << " * sizeof("
85 << baseType
86 << "), &"
87 << parentName
88 << ");\n";
89
90 handleError(out, mode);
91 }
92
93 emitReaderWriterEmbedded(
94 out,
95 name,
96 isReader /* nameIsPointer */,
97 parcelObj,
98 parcelObjIsPointer,
99 isReader,
100 mode,
101 parentName,
102 "0 /* parentOffset */");
103}
104
105void ArrayType::emitReaderWriterEmbedded(
106 Formatter &out,
107 const std::string &name,
108 bool nameIsPointer,
109 const std::string &parcelObj,
110 bool parcelObjIsPointer,
111 bool isReader,
112 ErrorMode mode,
113 const std::string &parentName,
114 const std::string &offsetText) const {
115 if (!mElementType->needsEmbeddedReadWrite()) {
116 return;
117 }
118
119 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
120
121 std::string baseExtra;
122 std::string baseType = mElementType->getCppType(&baseExtra);
123
124 out << "for (size_t _aidl_index = 0; _aidl_index < "
125 << mDimension
126 << "; ++_aidl_index) {\n";
127
128 out.indent();
129
130 mElementType->emitReaderWriterEmbedded(
131 out,
132 name + "[_aidl_index]",
133 false /* nameIsPointer */,
134 parcelObj,
135 parcelObjIsPointer,
136 isReader,
137 mode,
138 parentName,
139 offsetText + " + _aidl_index * sizeof(" + baseType + ")");
140
141 out.unindent();
142
143 out << "}\n\n";
144}
145
146bool ArrayType::needsEmbeddedReadWrite() const {
147 return mElementType->needsEmbeddedReadWrite();
148}
149
Andreas Huberc9410c72016-07-28 12:18:40 -0700150} // namespace android
151