• 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 
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