//===- SectionMap.cpp -----------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include <mcld/Object/SectionMap.h> #include <mcld/ADT/StringHash.h> #include <cassert> #include <cstring> using namespace mcld; SectionMap::NamePair SectionMap::NullName; //===----------------------------------------------------------------------===// // SectionMap::NamePair //===----------------------------------------------------------------------===// SectionMap::NamePair::NamePair() : hash(-1) { } SectionMap::NamePair::NamePair(const std::string& pFrom, const std::string& pTo) : from(pFrom), to(pTo) { hash = SectionMap::hash(pFrom); } bool SectionMap::NamePair::isNull() const { return (&NullName == this); } //===----------------------------------------------------------------------===// // SectionMap //===----------------------------------------------------------------------===// const SectionMap::NamePair& SectionMap::find(const std::string& pFrom) const { unsigned int hash = SectionMap::hash(pFrom); return find(pFrom, hash); } SectionMap::NamePair& SectionMap::find(const std::string& pFrom) { unsigned int hash = SectionMap::hash(pFrom); return find(pFrom, hash); } const SectionMap::NamePair& SectionMap::find(const std::string& pFrom, unsigned int pHash) const { NamePairList::const_iterator name_hash, nEnd = m_NamePairList.end(); for (name_hash = m_NamePairList.begin(); name_hash != nEnd; ++name_hash) { if (matched(*name_hash, pFrom, pHash)) { return *name_hash; } } return NullName; } SectionMap::NamePair& SectionMap::find(const std::string& pFrom, unsigned int pHash) { NamePairList::iterator name_hash, nEnd = m_NamePairList.end(); for (name_hash = m_NamePairList.begin(); name_hash != nEnd; ++name_hash) { if (matched(*name_hash, pFrom, pHash)) { return *name_hash; } } return NullName; } SectionMap::NamePair& SectionMap::append(const std::string &pFrom, const std::string &pTo, bool &pExist) { NamePair& result = find(pFrom); if (!result.isNull()) { pExist = true; return result; } pExist = false; NamePair entry(pFrom, pTo); m_NamePairList.push_back(entry); return m_NamePairList.back(); } bool SectionMap::matched(const NamePair& pNamePair, const std::string& pInput, unsigned int pHashValue) const { if ('*' == pNamePair.from[0]) return true; if (pNamePair.from.size() > pInput.size()) return false; if (!StringHash<ES>::may_include(pNamePair.hash, pHashValue)) return false; if (0 == strncmp(pInput.c_str(), pNamePair.from.c_str(), pNamePair.from.size())) { return true; } return false; } unsigned int SectionMap::hash(const std::string& pString) { static StringHash<ES> hash_func; return hash_func(pString); }