11e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang/*
21e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * Copyright 2012, The Android Open Source Project
31e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang *
41e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
51e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * you may not use this file except in compliance with the License.
61e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * You may obtain a copy of the License at
71e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang *
81e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang *     http://www.apache.org/licenses/LICENSE-2.0
91e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang *
101e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * Unless required by applicable law or agreed to in writing, software
111e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
121e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * See the License for the specific language governing permissions and
141e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * limitations under the License.
151e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang */
161e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
171e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang//===----------------------------------------------------------------------===//
181e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang// This file implements RSInfo::write()
191e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang//===----------------------------------------------------------------------===//
201e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
21e198abec6c5e3eab380ccf6897b0a0b9c2dd92ddStephen Hines#include "bcc/Renderscript/RSInfo.h"
221e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
23ef73a242762bcd8113b9b65ceccbe7d909b5acbcZonr Chang#include "bcc/Support/Log.h"
24c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/Support/OutputFile.h"
251e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
261e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changusing namespace bcc;
271e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
281e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changnamespace {
291e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
301e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changtemplate<typename ItemType, typename ItemContainer> inline bool
311e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changhelper_adapt_list_item(ItemType &pResult, const RSInfo &pInfo,
321e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang                       const typename ItemContainer::const_iterator &pItem);
331e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
341e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
351e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changtemplate<> inline bool
361e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changhelper_adapt_list_item<rsinfo::PragmaItem, RSInfo::PragmaListTy>(
371e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    rsinfo::PragmaItem &pResult,
381e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const RSInfo &pInfo,
391e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const RSInfo::PragmaListTy::const_iterator &pItem) {
401e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  pResult.key = pInfo.getStringIdxInPool(pItem->first);
411e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  pResult.value = pInfo.getStringIdxInPool(pItem->second);
421e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
431e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (pResult.key == rsinfo::gInvalidStringIndex) {
441e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("RS pragma list contains invalid string '%s' for key.", pItem->first);
451e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
461e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
471e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
481e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (pResult.value == rsinfo::gInvalidStringIndex) {
491e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("RS pragma list contains invalid string '%s' for value.",
501e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          pItem->second);
511e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
521e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
531e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
541e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return true;
551e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
561e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
571e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changtemplate<> inline bool
581e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changhelper_adapt_list_item<rsinfo::ObjectSlotItem, RSInfo::ObjectSlotListTy>(
591e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    rsinfo::ObjectSlotItem &pResult,
601e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const RSInfo &pInfo,
611e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const RSInfo::ObjectSlotListTy::const_iterator &pItem) {
621e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  pResult.slot = *pItem;
631e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return true;
641e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
651e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
661e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changtemplate<> inline bool
671e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changhelper_adapt_list_item<rsinfo::ExportVarNameItem, RSInfo::ExportVarNameListTy>(
681e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    rsinfo::ExportVarNameItem &pResult,
691e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const RSInfo &pInfo,
701e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const RSInfo::ExportVarNameListTy::const_iterator &pItem) {
711e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  pResult.name = pInfo.getStringIdxInPool(*pItem);
721e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
731e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (pResult.name == rsinfo::gInvalidStringIndex) {
741e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("RS export vars contains invalid string '%s' for name.", *pItem);
751e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
761e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
771e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
781e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return true;
791e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
801e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
811e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changtemplate<> inline bool
821e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changhelper_adapt_list_item<rsinfo::ExportFuncNameItem,
831e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang                       RSInfo::ExportFuncNameListTy>(
841e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    rsinfo::ExportFuncNameItem &pResult,
851e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const RSInfo &pInfo,
861e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const RSInfo::ExportFuncNameListTy::const_iterator &pItem) {
871e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  pResult.name = pInfo.getStringIdxInPool(*pItem);
881e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
891e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (pResult.name == rsinfo::gInvalidStringIndex) {
901e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("RS export funcs contains invalid string '%s' for name.", *pItem);
911e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
921e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
931e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
941e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return true;
951e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
961e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
971e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changtemplate<> inline bool
981e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changhelper_adapt_list_item<rsinfo::ExportForeachFuncItem,
991e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang                       RSInfo::ExportForeachFuncListTy>(
1001e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    rsinfo::ExportForeachFuncItem &pResult,
1011e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const RSInfo &pInfo,
1021e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    const RSInfo::ExportForeachFuncListTy::const_iterator &pItem) {
1031e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  pResult.name = pInfo.getStringIdxInPool(pItem->first);
1041e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  pResult.signature = pItem->second;
1051e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1061e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (pResult.name == rsinfo::gInvalidStringIndex) {
1071e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("RS export foreach contains invalid string '%s' for name.",
1081e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          pItem->first);
1091e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
1101e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1111e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1121e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return true;
1131e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
1141e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1151e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changtemplate<typename ItemType, typename ItemContainer>
1161e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changinline bool helper_write_list(OutputFile &pOutput,
1171e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang                              const RSInfo &pInfo,
1181e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang                              const rsinfo::ListHeader &pHeader,
1191e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang                              ItemContainer &pList) {
1201e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  ItemType item;
1211e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1221e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  for (typename ItemContainer::const_iterator item_iter = pList.begin(),
1231e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          item_end = pList.end(); item_iter != item_end; item_iter++) {
1241e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    // Convert each entry in the pList to ItemType.
1251e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    if (!helper_adapt_list_item<ItemType, ItemContainer>(item,
1261e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang                                                         pInfo,
1271e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang                                                         item_iter)) {
1281e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      return false;
1291e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    }
1301e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    // And write out an item.
1311e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    if (pOutput.write(&item, sizeof(item)) != sizeof(item)) {
1321e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      ALOGE("Cannot write out item of %s for RSInfo file %s! (%s)",
1331e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang            rsinfo::GetItemTypeName<ItemType>(), pOutput.getName().c_str(),
1341e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang            pOutput.getErrorMessage().c_str());
1351e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang      return false;
1361e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    }
1371e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1381e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1391e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return true;
1401e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
1411e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1421e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang} // end anonymous namespace
1431e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1441e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changbool RSInfo::write(OutputFile &pOutput) {
1451e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  off_t initial_offset = pOutput.tell();
1461e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  const char *output_filename = pOutput.getName().c_str();
1471e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1481e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (pOutput.hasError()) {
1491e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("Invalid RS info file %s for output! (%s)",
1501e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          output_filename, pOutput.getErrorMessage().c_str());
1511e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
1521e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1531e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1541e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Layout.
1551e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (!layout(initial_offset)) {
1561e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
1571e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1581e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1591e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Write header.
1601e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (pOutput.write(&mHeader, sizeof(mHeader)) != sizeof(mHeader)) {
1611e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("Cannot write out the header for RSInfo file %s! (%s)",
1621e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          output_filename, pOutput.getErrorMessage().c_str());
1631e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
1641e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1651e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1661e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Write string pool.
1671e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (static_cast<size_t>(pOutput.write(mStringPool, mHeader.strPoolSize))
1681e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          != mHeader.strPoolSize) {
1691e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    ALOGE("Cannot write out the string pool for RSInfo file %s! (%s)",
1701e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang          output_filename, pOutput.getErrorMessage().c_str());
1711e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
1721e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1731e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1741e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Write pragmaList.
1751e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (!helper_write_list<rsinfo::PragmaItem, PragmaListTy>
1761e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang        (pOutput, *this, mHeader.pragmaList, mPragmas)) {
1771e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
1781e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1791e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1801e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Write objectSlotList.
1811e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (!helper_write_list<rsinfo::ObjectSlotItem, ObjectSlotListTy>
1821e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang        (pOutput, *this, mHeader.objectSlotList, mObjectSlots)) {
1831e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
1841e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1851e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1861e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Write exportVarNameList.
1871e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (!helper_write_list<rsinfo::ExportVarNameItem, ExportVarNameListTy>
1881e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang        (pOutput, *this, mHeader.exportVarNameList, mExportVarNames)) {
1891e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
1901e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1911e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1921e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Write exportFuncNameList.
1931e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (!helper_write_list<rsinfo::ExportFuncNameItem, ExportFuncNameListTy>
1941e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang        (pOutput, *this, mHeader.exportFuncNameList, mExportFuncNames)) {
1951e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
1961e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
1971e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
1981e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  // Write exportForeachFuncList.
1991e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  if (!helper_write_list<rsinfo::ExportForeachFuncItem, ExportForeachFuncListTy>
2001e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang        (pOutput, *this, mHeader.exportForeachFuncList, mExportForeachFuncs)) {
2011e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang    return false;
2021e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  }
2031e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang
2041e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang  return true;
2051e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang}
206