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

#include "lldb/API/SBSection.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBTarget.h"
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Symbol/ObjectFile.h"


using namespace lldb;
using namespace lldb_private;


SBSection::SBSection () :
    m_opaque_wp ()
{
}

SBSection::SBSection (const SBSection &rhs) :
    m_opaque_wp (rhs.m_opaque_wp)
{
}



SBSection::SBSection (const lldb::SectionSP &section_sp) :
    m_opaque_wp () // Don't init with section_sp otherwise this will throw if section_sp doesn't contain a valid Section *
{
    if (section_sp)
        m_opaque_wp = section_sp;
}

const SBSection &
SBSection::operator = (const SBSection &rhs)
{
    m_opaque_wp = rhs.m_opaque_wp;
    return *this;
}

SBSection::~SBSection ()
{
}

bool
SBSection::IsValid () const
{
    SectionSP section_sp (GetSP());
    return section_sp && section_sp->GetModule().get() != NULL;
}

const char *
SBSection::GetName ()
{
    SectionSP section_sp (GetSP());
    if (section_sp)
        return section_sp->GetName().GetCString();
    return NULL;
}


lldb::SBSection
SBSection::FindSubSection (const char *sect_name)
{
    lldb::SBSection sb_section;
    if (sect_name)
    {
        SectionSP section_sp (GetSP());
        if (section_sp)
        {
            ConstString const_sect_name(sect_name);
            sb_section.SetSP(section_sp->GetChildren ().FindSectionByName(const_sect_name));
        }
    }
    return sb_section;
}

size_t
SBSection::GetNumSubSections ()
{
    SectionSP section_sp (GetSP());
    if (section_sp)
        return section_sp->GetChildren ().GetSize();
    return 0;
}

lldb::SBSection
SBSection::GetSubSectionAtIndex (size_t idx)
{
    lldb::SBSection sb_section;
    SectionSP section_sp (GetSP());
    if (section_sp)
        sb_section.SetSP (section_sp->GetChildren ().GetSectionAtIndex(idx));
    return sb_section;
}

lldb::SectionSP
SBSection::GetSP() const
{
    return m_opaque_wp.lock();
}

void
SBSection::SetSP(const lldb::SectionSP &section_sp)
{
    m_opaque_wp = section_sp;
}

lldb::addr_t
SBSection::GetFileAddress ()
{
    lldb::addr_t file_addr = LLDB_INVALID_ADDRESS;
    SectionSP section_sp (GetSP());
    if (section_sp)
        return section_sp->GetFileAddress();
    return file_addr;
}

lldb::addr_t
SBSection::GetLoadAddress (lldb::SBTarget &sb_target)
{
    TargetSP target_sp(sb_target.GetSP());
    if (target_sp)
    {
        SectionSP section_sp (GetSP());
        if (section_sp)
            return section_sp->GetLoadBaseAddress(target_sp.get());
    }
    return LLDB_INVALID_ADDRESS;
    
}



lldb::addr_t
SBSection::GetByteSize ()
{
    SectionSP section_sp (GetSP());
    if (section_sp)
        return section_sp->GetByteSize();
    return 0;
}

uint64_t
SBSection::GetFileOffset ()
{
    SectionSP section_sp (GetSP());
    if (section_sp)
    {
        ModuleSP module_sp (section_sp->GetModule());
        if (module_sp)
        {
            ObjectFile *objfile = module_sp->GetObjectFile();
            if (objfile)
                return objfile->GetFileOffset() + section_sp->GetFileOffset();
        }
    }
    return UINT64_MAX;
}

uint64_t
SBSection::GetFileByteSize ()
{
    SectionSP section_sp (GetSP());
    if (section_sp)
        return section_sp->GetFileSize();
    return 0;
}

SBData
SBSection::GetSectionData ()
{
    return GetSectionData (0, UINT64_MAX);
}

SBData
SBSection::GetSectionData (uint64_t offset, uint64_t size)
{
    SBData sb_data;
    SectionSP section_sp (GetSP());
    if (section_sp)
    {
        const uint64_t sect_file_size = section_sp->GetFileSize();
        if (sect_file_size > 0)
        {
            ModuleSP module_sp (section_sp->GetModule());
            if (module_sp)
            {
                ObjectFile *objfile = module_sp->GetObjectFile();
                if (objfile)
                {
                    const uint64_t sect_file_offset = objfile->GetFileOffset() + section_sp->GetFileOffset();
                    const uint64_t file_offset = sect_file_offset + offset;
                    uint64_t file_size = size;
                    if (file_size == UINT64_MAX)
                    {
                        file_size = section_sp->GetByteSize();
                        if (file_size > offset)
                            file_size -= offset;
                        else
                            file_size = 0;
                    }
                    DataBufferSP data_buffer_sp (objfile->GetFileSpec().ReadFileContents (file_offset, file_size));
                    if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0)
                    {
                        DataExtractorSP data_extractor_sp (new DataExtractor (data_buffer_sp, 
                                                                              objfile->GetByteOrder(), 
                                                                              objfile->GetAddressByteSize()));
                        
                        sb_data.SetOpaque (data_extractor_sp);
                    }
                }
            }
        }
    }
    return sb_data;
}

SectionType
SBSection::GetSectionType ()
{
    SectionSP section_sp (GetSP());
    if (section_sp.get())
        return section_sp->GetType();
    return eSectionTypeInvalid;
}


bool
SBSection::operator == (const SBSection &rhs)
{
    SectionSP lhs_section_sp (GetSP());
    SectionSP rhs_section_sp (rhs.GetSP());
    if (lhs_section_sp && rhs_section_sp)
        return lhs_section_sp == rhs_section_sp;
    return false;
}

bool
SBSection::operator != (const SBSection &rhs)
{
    SectionSP lhs_section_sp (GetSP());
    SectionSP rhs_section_sp (rhs.GetSP());
    return lhs_section_sp != rhs_section_sp;
}

bool
SBSection::GetDescription (SBStream &description)
{
    Stream &strm = description.ref();

    SectionSP section_sp (GetSP());
    if (section_sp)
    {
        const addr_t file_addr = section_sp->GetFileAddress();
        strm.Printf ("[0x%16.16" PRIx64 "-0x%16.16" PRIx64 ") ", file_addr, file_addr + section_sp->GetByteSize());
        section_sp->DumpName(&strm);
    }
    else
    {
        strm.PutCString ("No value");
    }

    return true;
}

