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 26using namespace bcc; 27 28namespace { 29 30template<typename ItemType, typename ItemContainer> inline bool 31helper_adapt_list_item(ItemType &pResult, const RSInfo &pInfo, 32 const typename ItemContainer::const_iterator &pItem); 33 34 35template<> inline bool 36helper_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 57template<> inline bool 58helper_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 66template<> inline bool 67helper_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 81template<> inline bool 82helper_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 97template<> inline bool 98helper_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 115template<typename ItemType, typename ItemContainer> 116inline 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 144bool 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