/* * Copyright 2012, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ //===----------------------------------------------------------------------===// // This file implements RSInfo::write() //===----------------------------------------------------------------------===// #include "bcc/Renderscript/RSInfo.h" #include "bcc/Support/Log.h" #include "bcc/Support/OutputFile.h" using namespace bcc; namespace { template<typename ItemType, typename ItemContainer> inline bool helper_adapt_list_item(ItemType &pResult, const RSInfo &pInfo, const typename ItemContainer::const_iterator &pItem); template<> inline bool helper_adapt_list_item<rsinfo::DependencyTableItem, RSInfo::DependencyTableTy>( rsinfo::DependencyTableItem &pResult, const RSInfo &pInfo, const RSInfo::DependencyTableTy::const_iterator &pItem) { pResult.id = pInfo.getStringIdxInPool(pItem->first); pResult.sha1 = pInfo.getStringIdxInPool(reinterpret_cast<const char *>(pItem->second)); if (pResult.id == rsinfo::gInvalidStringIndex) { ALOGE("RS dependency table contains invalid source id string '%s'.", pItem->first); return false; } if (pResult.sha1 == rsinfo::gInvalidStringIndex) { ALOGE("RS dependency table contains invalid SHA-1 checksum string in '%s'.", pItem->first); return false; } return true; } template<> inline bool helper_adapt_list_item<rsinfo::PragmaItem, RSInfo::PragmaListTy>( rsinfo::PragmaItem &pResult, const RSInfo &pInfo, const RSInfo::PragmaListTy::const_iterator &pItem) { pResult.key = pInfo.getStringIdxInPool(pItem->first); pResult.value = pInfo.getStringIdxInPool(pItem->second); if (pResult.key == rsinfo::gInvalidStringIndex) { ALOGE("RS pragma list contains invalid string '%s' for key.", pItem->first); return false; } if (pResult.value == rsinfo::gInvalidStringIndex) { ALOGE("RS pragma list contains invalid string '%s' for value.", pItem->second); return false; } return true; } template<> inline bool helper_adapt_list_item<rsinfo::ObjectSlotItem, RSInfo::ObjectSlotListTy>( rsinfo::ObjectSlotItem &pResult, const RSInfo &pInfo, const RSInfo::ObjectSlotListTy::const_iterator &pItem) { pResult.slot = *pItem; return true; } template<> inline bool helper_adapt_list_item<rsinfo::ExportVarNameItem, RSInfo::ExportVarNameListTy>( rsinfo::ExportVarNameItem &pResult, const RSInfo &pInfo, const RSInfo::ExportVarNameListTy::const_iterator &pItem) { pResult.name = pInfo.getStringIdxInPool(*pItem); if (pResult.name == rsinfo::gInvalidStringIndex) { ALOGE("RS export vars contains invalid string '%s' for name.", *pItem); return false; } return true; } template<> inline bool helper_adapt_list_item<rsinfo::ExportFuncNameItem, RSInfo::ExportFuncNameListTy>( rsinfo::ExportFuncNameItem &pResult, const RSInfo &pInfo, const RSInfo::ExportFuncNameListTy::const_iterator &pItem) { pResult.name = pInfo.getStringIdxInPool(*pItem); if (pResult.name == rsinfo::gInvalidStringIndex) { ALOGE("RS export funcs contains invalid string '%s' for name.", *pItem); return false; } return true; } template<> inline bool helper_adapt_list_item<rsinfo::ExportForeachFuncItem, RSInfo::ExportForeachFuncListTy>( rsinfo::ExportForeachFuncItem &pResult, const RSInfo &pInfo, const RSInfo::ExportForeachFuncListTy::const_iterator &pItem) { pResult.name = pInfo.getStringIdxInPool(pItem->first); pResult.signature = pItem->second; if (pResult.name == rsinfo::gInvalidStringIndex) { ALOGE("RS export foreach contains invalid string '%s' for name.", pItem->first); return false; } return true; } template<typename ItemType, typename ItemContainer> inline bool helper_write_list(OutputFile &pOutput, const RSInfo &pInfo, const rsinfo::ListHeader &pHeader, ItemContainer &pList) { ItemType item; for (typename ItemContainer::const_iterator item_iter = pList.begin(), item_end = pList.end(); item_iter != item_end; item_iter++) { // Convert each entry in the pList to ItemType. if (!helper_adapt_list_item<ItemType, ItemContainer>(item, pInfo, item_iter)) { return false; } // And write out an item. if (pOutput.write(&item, sizeof(item)) != sizeof(item)) { ALOGE("Cannot write out item of %s for RSInfo file %s! (%s)", rsinfo::GetItemTypeName<ItemType>(), pOutput.getName().c_str(), pOutput.getErrorMessage().c_str()); return false; } } return true; } } // end anonymous namespace bool RSInfo::write(OutputFile &pOutput) { off_t initial_offset = pOutput.tell(); const char *output_filename = pOutput.getName().c_str(); if (pOutput.hasError()) { ALOGE("Invalid RS info file %s for output! (%s)", output_filename, pOutput.getErrorMessage().c_str()); return false; } // Layout. if (!layout(initial_offset)) { return false; } // Write header. if (pOutput.write(&mHeader, sizeof(mHeader)) != sizeof(mHeader)) { ALOGE("Cannot write out the header for RSInfo file %s! (%s)", output_filename, pOutput.getErrorMessage().c_str()); return false; } // Write string pool. if (static_cast<size_t>(pOutput.write(mStringPool, mHeader.strPoolSize)) != mHeader.strPoolSize) { ALOGE("Cannot write out the string pool for RSInfo file %s! (%s)", output_filename, pOutput.getErrorMessage().c_str()); return false; } // Write dependencyTable. if (!helper_write_list<rsinfo::DependencyTableItem, DependencyTableTy> (pOutput, *this, mHeader.dependencyTable, mDependencyTable)) { return false; } // Write pragmaList. if (!helper_write_list<rsinfo::PragmaItem, PragmaListTy> (pOutput, *this, mHeader.pragmaList, mPragmas)) { return false; } // Write objectSlotList. if (!helper_write_list<rsinfo::ObjectSlotItem, ObjectSlotListTy> (pOutput, *this, mHeader.objectSlotList, mObjectSlots)) { return false; } // Write exportVarNameList. if (!helper_write_list<rsinfo::ExportVarNameItem, ExportVarNameListTy> (pOutput, *this, mHeader.exportVarNameList, mExportVarNames)) { return false; } // Write exportFuncNameList. if (!helper_write_list<rsinfo::ExportFuncNameItem, ExportFuncNameListTy> (pOutput, *this, mHeader.exportFuncNameList, mExportFuncNames)) { return false; } // Write exportForeachFuncList. if (!helper_write_list<rsinfo::ExportForeachFuncItem, ExportForeachFuncListTy> (pOutput, *this, mHeader.exportForeachFuncList, mExportForeachFuncs)) { return false; } return true; }