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

