1 /*
2 * Copyright 2012, 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 //===----------------------------------------------------------------------===//
18 // This file implements RSInfo::write()
19 //===----------------------------------------------------------------------===//
20
21 #include "bcc/Renderscript/RSInfo.h"
22
23 #include "bcc/Support/Log.h"
24 #include "bcc/Support/OutputFile.h"
25
26 using namespace bcc;
27
28 namespace {
29
30 template<typename ItemType, typename ItemContainer> inline bool
31 helper_adapt_list_item(ItemType &pResult, const RSInfo &pInfo,
32 const typename ItemContainer::const_iterator &pItem);
33
34
35 template<> inline bool
helper_adapt_list_item(rsinfo::PragmaItem & pResult,const RSInfo & pInfo,const RSInfo::PragmaListTy::const_iterator & pItem)36 helper_adapt_list_item<rsinfo::PragmaItem, RSInfo::PragmaListTy>(
37 rsinfo::PragmaItem &pResult,
38 const RSInfo &pInfo,
39 const RSInfo::PragmaListTy::const_iterator &pItem) {
40 pResult.key = pInfo.getStringIdxInPool(pItem->first);
41 pResult.value = pInfo.getStringIdxInPool(pItem->second);
42
43 if (pResult.key == rsinfo::gInvalidStringIndex) {
44 ALOGE("RS pragma list contains invalid string '%s' for key.", pItem->first);
45 return false;
46 }
47
48 if (pResult.value == rsinfo::gInvalidStringIndex) {
49 ALOGE("RS pragma list contains invalid string '%s' for value.",
50 pItem->second);
51 return false;
52 }
53
54 return true;
55 }
56
57 template<> inline bool
helper_adapt_list_item(rsinfo::ObjectSlotItem & pResult,const RSInfo & pInfo,const RSInfo::ObjectSlotListTy::const_iterator & pItem)58 helper_adapt_list_item<rsinfo::ObjectSlotItem, RSInfo::ObjectSlotListTy>(
59 rsinfo::ObjectSlotItem &pResult,
60 const RSInfo &pInfo,
61 const RSInfo::ObjectSlotListTy::const_iterator &pItem) {
62 pResult.slot = *pItem;
63 return true;
64 }
65
66 template<> inline bool
helper_adapt_list_item(rsinfo::ExportVarNameItem & pResult,const RSInfo & pInfo,const RSInfo::ExportVarNameListTy::const_iterator & pItem)67 helper_adapt_list_item<rsinfo::ExportVarNameItem, RSInfo::ExportVarNameListTy>(
68 rsinfo::ExportVarNameItem &pResult,
69 const RSInfo &pInfo,
70 const RSInfo::ExportVarNameListTy::const_iterator &pItem) {
71 pResult.name = pInfo.getStringIdxInPool(*pItem);
72
73 if (pResult.name == rsinfo::gInvalidStringIndex) {
74 ALOGE("RS export vars contains invalid string '%s' for name.", *pItem);
75 return false;
76 }
77
78 return true;
79 }
80
81 template<> inline bool
helper_adapt_list_item(rsinfo::ExportFuncNameItem & pResult,const RSInfo & pInfo,const RSInfo::ExportFuncNameListTy::const_iterator & pItem)82 helper_adapt_list_item<rsinfo::ExportFuncNameItem,
83 RSInfo::ExportFuncNameListTy>(
84 rsinfo::ExportFuncNameItem &pResult,
85 const RSInfo &pInfo,
86 const RSInfo::ExportFuncNameListTy::const_iterator &pItem) {
87 pResult.name = pInfo.getStringIdxInPool(*pItem);
88
89 if (pResult.name == rsinfo::gInvalidStringIndex) {
90 ALOGE("RS export funcs contains invalid string '%s' for name.", *pItem);
91 return false;
92 }
93
94 return true;
95 }
96
97 template<> inline bool
helper_adapt_list_item(rsinfo::ExportForeachFuncItem & pResult,const RSInfo & pInfo,const RSInfo::ExportForeachFuncListTy::const_iterator & pItem)98 helper_adapt_list_item<rsinfo::ExportForeachFuncItem,
99 RSInfo::ExportForeachFuncListTy>(
100 rsinfo::ExportForeachFuncItem &pResult,
101 const RSInfo &pInfo,
102 const RSInfo::ExportForeachFuncListTy::const_iterator &pItem) {
103 pResult.name = pInfo.getStringIdxInPool(pItem->first);
104 pResult.signature = pItem->second;
105
106 if (pResult.name == rsinfo::gInvalidStringIndex) {
107 ALOGE("RS export foreach contains invalid string '%s' for name.",
108 pItem->first);
109 return false;
110 }
111
112 return true;
113 }
114
115 template<typename ItemType, typename ItemContainer>
helper_write_list(OutputFile & pOutput,const RSInfo & pInfo,const rsinfo::ListHeader & pHeader,ItemContainer & pList)116 inline bool helper_write_list(OutputFile &pOutput,
117 const RSInfo &pInfo,
118 const rsinfo::ListHeader &pHeader,
119 ItemContainer &pList) {
120 ItemType item;
121
122 for (typename ItemContainer::const_iterator item_iter = pList.begin(),
123 item_end = pList.end(); item_iter != item_end; item_iter++) {
124 // Convert each entry in the pList to ItemType.
125 if (!helper_adapt_list_item<ItemType, ItemContainer>(item,
126 pInfo,
127 item_iter)) {
128 return false;
129 }
130 // And write out an item.
131 if (pOutput.write(&item, sizeof(item)) != sizeof(item)) {
132 ALOGE("Cannot write out item of %s for RSInfo file %s! (%s)",
133 rsinfo::GetItemTypeName<ItemType>(), pOutput.getName().c_str(),
134 pOutput.getErrorMessage().c_str());
135 return false;
136 }
137 }
138
139 return true;
140 }
141
142 } // end anonymous namespace
143
write(OutputFile & pOutput)144 bool RSInfo::write(OutputFile &pOutput) {
145 off_t initial_offset = pOutput.tell();
146 const char *output_filename = pOutput.getName().c_str();
147
148 if (pOutput.hasError()) {
149 ALOGE("Invalid RS info file %s for output! (%s)",
150 output_filename, pOutput.getErrorMessage().c_str());
151 return false;
152 }
153
154 // Layout.
155 if (!layout(initial_offset)) {
156 return false;
157 }
158
159 // Write header.
160 if (pOutput.write(&mHeader, sizeof(mHeader)) != sizeof(mHeader)) {
161 ALOGE("Cannot write out the header for RSInfo file %s! (%s)",
162 output_filename, pOutput.getErrorMessage().c_str());
163 return false;
164 }
165
166 // Write string pool.
167 if (static_cast<size_t>(pOutput.write(mStringPool, mHeader.strPoolSize))
168 != mHeader.strPoolSize) {
169 ALOGE("Cannot write out the string pool for RSInfo file %s! (%s)",
170 output_filename, pOutput.getErrorMessage().c_str());
171 return false;
172 }
173
174 // Write pragmaList.
175 if (!helper_write_list<rsinfo::PragmaItem, PragmaListTy>
176 (pOutput, *this, mHeader.pragmaList, mPragmas)) {
177 return false;
178 }
179
180 // Write objectSlotList.
181 if (!helper_write_list<rsinfo::ObjectSlotItem, ObjectSlotListTy>
182 (pOutput, *this, mHeader.objectSlotList, mObjectSlots)) {
183 return false;
184 }
185
186 // Write exportVarNameList.
187 if (!helper_write_list<rsinfo::ExportVarNameItem, ExportVarNameListTy>
188 (pOutput, *this, mHeader.exportVarNameList, mExportVarNames)) {
189 return false;
190 }
191
192 // Write exportFuncNameList.
193 if (!helper_write_list<rsinfo::ExportFuncNameItem, ExportFuncNameListTy>
194 (pOutput, *this, mHeader.exportFuncNameList, mExportFuncNames)) {
195 return false;
196 }
197
198 // Write exportForeachFuncList.
199 if (!helper_write_list<rsinfo::ExportForeachFuncItem, ExportForeachFuncListTy>
200 (pOutput, *this, mHeader.exportForeachFuncList, mExportForeachFuncs)) {
201 return false;
202 }
203
204 return true;
205 }
206