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