| //===- 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); |
| } |
| |