blob: d855c31976e05550d1464ae8438097bf5f3751f0 [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
Andreas Huber881227d2016-08-02 14:20:21 -070014std::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
36void ArrayType::emitReaderWriter(
37 Formatter &out,
38 const std::string &name,
39 const std::string &parcelObj,
40 bool parcelObjIsPointer,
41 bool isReader,
42 ErrorMode mode) const {
43 std::string baseExtra;
44 std::string baseType = mElementType->getCppType(&baseExtra);
45
46 const std::string parentName = "_aidl_" + name + "_parent";
47
48 out << "size_t " << parentName << ";\n\n";
49
50 const std::string parcelObjDeref =
51 parcelObj + (parcelObjIsPointer ? "->" : ".");
52
53 if (isReader) {
54 out << name
55 << " = (const "
56 << baseType
57 << " *)"
58 << parcelObjDeref
59 << "readBuffer(&"
60 << parentName
61 << ");\n\n";
62
63 out << "if (" << name << " == nullptr) {\n";
64
65 out.indent();
66
67 out << "_aidl_err = ::android::UNKNOWN_ERROR;\n";
68 handleError2(out, mode);
69
70 out.unindent();
71 out << "}\n\n";
72 } else {
73 out << "_aidl_err = "
74 << parcelObjDeref
75 << "writeBuffer("
76 << name
77 << ", "
78 << mDimension
79 << " * sizeof("
80 << baseType
81 << "), &"
82 << parentName
83 << ");\n";
84
85 handleError(out, mode);
86 }
87
88 emitReaderWriterEmbedded(
89 out,
90 name,
91 isReader /* nameIsPointer */,
92 parcelObj,
93 parcelObjIsPointer,
94 isReader,
95 mode,
96 parentName,
97 "0 /* parentOffset */");
98}
99
100void ArrayType::emitReaderWriterEmbedded(
101 Formatter &out,
102 const std::string &name,
103 bool nameIsPointer,
104 const std::string &parcelObj,
105 bool parcelObjIsPointer,
106 bool isReader,
107 ErrorMode mode,
108 const std::string &parentName,
109 const std::string &offsetText) const {
110 if (!mElementType->needsEmbeddedReadWrite()) {
111 return;
112 }
113
114 const std::string nameDeref = name + (nameIsPointer ? "->" : ".");
115
116 std::string baseExtra;
117 std::string baseType = mElementType->getCppType(&baseExtra);
118
119 out << "for (size_t _aidl_index = 0; _aidl_index < "
120 << mDimension
121 << "; ++_aidl_index) {\n";
122
123 out.indent();
124
125 mElementType->emitReaderWriterEmbedded(
126 out,
127 name + "[_aidl_index]",
128 false /* nameIsPointer */,
129 parcelObj,
130 parcelObjIsPointer,
131 isReader,
132 mode,
133 parentName,
134 offsetText + " + _aidl_index * sizeof(" + baseType + ")");
135
136 out.unindent();
137
138 out << "}\n\n";
139}
140
141bool ArrayType::needsEmbeddedReadWrite() const {
142 return mElementType->needsEmbeddedReadWrite();
143}
144
Andreas Huberc9410c72016-07-28 12:18:40 -0700145} // namespace android
146