//===-- DWARFDebugPubnamesSet.cpp -------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "DWARFDebugPubnamesSet.h"

#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Log.h"

#include "SymbolFileDWARF.h"

using namespace lldb_private;

DWARFDebugPubnamesSet::DWARFDebugPubnamesSet() :
    m_offset(DW_INVALID_OFFSET),
    m_header(),
    m_descriptors(),
    m_name_to_descriptor_index()
{
}

DWARFDebugPubnamesSet::DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset, dw_offset_t cu_die_offset, dw_offset_t cu_die_length) :
    m_offset(debug_aranges_offset),
    m_header(),
    m_descriptors(),
    m_name_to_descriptor_index()
{
    m_header.length = 10;               // set the length to only include the header right for now
    m_header.version = 2;               // The DWARF version number
    m_header.die_offset = cu_die_offset;// compile unit .debug_info offset
    m_header.die_length = cu_die_length;// compile unit .debug_info length
}

void
DWARFDebugPubnamesSet::AddDescriptor(dw_offset_t cu_rel_offset, const char* name)
{
    if (name && name[0])
    {
        // Adjust our header length
        m_header.length += strlen(name) + 1 + sizeof(dw_offset_t);
        Descriptor pubnameDesc(cu_rel_offset, name);
        m_descriptors.push_back(pubnameDesc);
    }
}

void
DWARFDebugPubnamesSet::Clear()
{
    m_offset = DW_INVALID_OFFSET;
    m_header.length = 10;
    m_header.version = 2;
    m_header.die_offset = DW_INVALID_OFFSET;
    m_header.die_length = 0;
    m_descriptors.clear();
}


//----------------------------------------------------------------------
// InitNameIndexes
//----------------------------------------------------------------------
void
DWARFDebugPubnamesSet::InitNameIndexes() const
{
    // Create the name index vector to be able to quickly search by name
    const size_t count = m_descriptors.size();
    for (uint32_t idx = 0; idx < count; ++idx)
    {
        const char* name = m_descriptors[idx].name.c_str();
        if (name && name[0])
            m_name_to_descriptor_index.insert(cstr_to_index_mmap::value_type(name, idx));
    }
}


bool
DWARFDebugPubnamesSet::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr)
{
    if (data.ValidOffset(*offset_ptr))
    {
        m_descriptors.clear();
        m_offset = *offset_ptr;
        m_header.length     = data.GetU32(offset_ptr);
        m_header.version    = data.GetU16(offset_ptr);
        m_header.die_offset = data.GetU32(offset_ptr);
        m_header.die_length = data.GetU32(offset_ptr);

        Descriptor pubnameDesc;
        while (data.ValidOffset(*offset_ptr))
        {
            pubnameDesc.offset  = data.GetU32(offset_ptr);

            if (pubnameDesc.offset)
            {
                const char* name = data.GetCStr(offset_ptr);
                if (name && name[0])
                {
                    pubnameDesc.name = name;
                    m_descriptors.push_back(pubnameDesc);
                }
            }
            else
                break;  // We are done if we get a zero 4 byte offset
        }

        return !m_descriptors.empty();
    }
    return false;
}

dw_offset_t
DWARFDebugPubnamesSet::GetOffsetOfNextEntry() const
{
    return m_offset + m_header.length + 4;
}

void
DWARFDebugPubnamesSet::Dump(Log *log) const
{
    log->Printf("Pubnames Header: length = 0x%8.8x, version = 0x%4.4x, die_offset = 0x%8.8x, die_length = 0x%8.8x",
        m_header.length,
        m_header.version,
        m_header.die_offset,
        m_header.die_length);

    bool verbose = log->GetVerbose();

    DescriptorConstIter pos;
    DescriptorConstIter end = m_descriptors.end();
    for (pos = m_descriptors.begin(); pos != end; ++pos)
    {
        if (verbose)
            log->Printf("0x%8.8x + 0x%8.8x = 0x%8.8x: %s", pos->offset, m_header.die_offset, pos->offset + m_header.die_offset, pos->name.c_str());
        else
            log->Printf("0x%8.8x: %s", pos->offset + m_header.die_offset, pos->name.c_str());
    }
}


void
DWARFDebugPubnamesSet::Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const
{
    if (!m_descriptors.empty() && m_name_to_descriptor_index.empty())
        InitNameIndexes();

    std::pair<cstr_to_index_mmap::const_iterator, cstr_to_index_mmap::const_iterator> range(m_name_to_descriptor_index.equal_range(name));
    for (cstr_to_index_mmap::const_iterator pos = range.first; pos != range.second; ++pos)
        die_offset_coll.push_back(m_header.die_offset + m_descriptors[(*pos).second].offset);
}

void
DWARFDebugPubnamesSet::Find(const RegularExpression& regex, std::vector<dw_offset_t>& die_offset_coll) const
{
    DescriptorConstIter pos;
    DescriptorConstIter end = m_descriptors.end();
    for (pos = m_descriptors.begin(); pos != end; ++pos)
    {
        if ( regex.Execute(pos->name.c_str()) )
            die_offset_coll.push_back(m_header.die_offset + pos->offset);
    }
}

