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