• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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