//===-- SBData.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/SBData.h"
#include "lldb/API/SBError.h"
#include "lldb/API/SBStream.h"

#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"


using namespace lldb;
using namespace lldb_private;

SBData::SBData () :
    m_opaque_sp(new DataExtractor())
{
}

SBData::SBData (const lldb::DataExtractorSP& data_sp) :
    m_opaque_sp (data_sp)
{
}

SBData::SBData(const SBData &rhs) :
    m_opaque_sp (rhs.m_opaque_sp)
{
}

const SBData &
SBData::operator = (const SBData &rhs)
{
    if (this != &rhs)
        m_opaque_sp = rhs.m_opaque_sp;
    return *this;
}

SBData::~SBData ()
{
}

void
SBData::SetOpaque (const lldb::DataExtractorSP &data_sp)
{
    m_opaque_sp = data_sp;
}

lldb_private::DataExtractor *
SBData::get() const
{
    return m_opaque_sp.get();
}

lldb_private::DataExtractor *
SBData::operator->() const
{
    return m_opaque_sp.operator->();
}

lldb::DataExtractorSP &
SBData::operator*()
{
    return m_opaque_sp;
}

const lldb::DataExtractorSP &
SBData::operator*() const
{
    return m_opaque_sp;
}

bool
SBData::IsValid()
{
    return m_opaque_sp.get() != NULL;
}

uint8_t
SBData::GetAddressByteSize ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    uint8_t value = 0;
    if (m_opaque_sp.get())
        value = m_opaque_sp->GetAddressByteSize();
    if (log)
        log->Printf ("SBData::GetAddressByteSize () => "
                     "(%i)", value);
    return value;
}

void
SBData::SetAddressByteSize (uint8_t addr_byte_size)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (m_opaque_sp.get())
        m_opaque_sp->SetAddressByteSize(addr_byte_size);
    if (log)
        log->Printf ("SBData::SetAddressByteSize (%i)", addr_byte_size);
}

void
SBData::Clear ()
{
    if (m_opaque_sp.get())
        m_opaque_sp->Clear();
}

size_t
SBData::GetByteSize ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    size_t value = 0;
    if (m_opaque_sp.get())
        value = m_opaque_sp->GetByteSize();
    if (log)
        log->Printf ("SBData::GetByteSize () => "
                     "(%lu)", value);
    return value;
}

lldb::ByteOrder
SBData::GetByteOrder ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    lldb::ByteOrder value = eByteOrderInvalid;
    if (m_opaque_sp.get())
        value = m_opaque_sp->GetByteOrder();
    if (log)
        log->Printf ("SBData::GetByteOrder () => "
                     "(%i)", value);
    return value;
}

void
SBData::SetByteOrder (lldb::ByteOrder endian)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (m_opaque_sp.get())
        m_opaque_sp->SetByteOrder(endian);
    if (log)
        log->Printf ("SBData::GetByteOrder (%i)", endian);
}


float
SBData::GetFloat (lldb::SBError& error, lldb::offset_t offset)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    float value = 0;
    if (!m_opaque_sp.get())
    {
        error.SetErrorString("no value to read from");
    }
    else
    {
        uint32_t old_offset = offset;
        value = m_opaque_sp->GetFloat(&offset);
        if (offset == old_offset)
            error.SetErrorString("unable to read data");
    }
    if (log)
        log->Printf ("SBData::GetFloat (error=%p,offset=%" PRIu64 ") => "
                     "(%f)", error.get(), offset, value);
    return value;
}

double
SBData::GetDouble (lldb::SBError& error, lldb::offset_t offset)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    double value = 0;
    if (!m_opaque_sp.get())
    {
        error.SetErrorString("no value to read from");
    }
    else
    {
        uint32_t old_offset = offset;
        value = m_opaque_sp->GetDouble(&offset);
        if (offset == old_offset)
            error.SetErrorString("unable to read data");
    }
    if (log)
        log->Printf ("SBData::GetDouble (error=%p,offset=%" PRIu64 ") => "
                     "(%f)", error.get(), offset, value);
    return value;
}

long double
SBData::GetLongDouble (lldb::SBError& error, lldb::offset_t offset)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    long double value = 0;
    if (!m_opaque_sp.get())
    {
        error.SetErrorString("no value to read from");
    }
    else
    {
        uint32_t old_offset = offset;
        value = m_opaque_sp->GetLongDouble(&offset);
        if (offset == old_offset)
            error.SetErrorString("unable to read data");
    }
    if (log)
        log->Printf ("SBData::GetLongDouble (error=%p,offset=%" PRIu64 ") => "
                     "(%Lf)", error.get(), offset, value);
    return value;
}

lldb::addr_t
SBData::GetAddress (lldb::SBError& error, lldb::offset_t offset)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    lldb::addr_t value = 0;
    if (!m_opaque_sp.get())
    {
        error.SetErrorString("no value to read from");
    }
    else
    {
        uint32_t old_offset = offset;
        value = m_opaque_sp->GetAddress(&offset);
        if (offset == old_offset)
            error.SetErrorString("unable to read data");
    }
    if (log)
        log->Printf ("SBData::GetAddress (error=%p,offset=%" PRIu64 ") => "
                     "(%p)", error.get(), offset, (void*)value);
    return value;
}

uint8_t
SBData::GetUnsignedInt8 (lldb::SBError& error, lldb::offset_t offset)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    uint8_t value = 0;
    if (!m_opaque_sp.get())
    {
        error.SetErrorString("no value to read from");
    }
    else
    {
        uint32_t old_offset = offset;
        value = m_opaque_sp->GetU8(&offset);
        if (offset == old_offset)
            error.SetErrorString("unable to read data");
    }
    if (log)
        log->Printf ("SBData::GetUnsignedInt8 (error=%p,offset=%" PRIu64 ") => "
                     "(%c)", error.get(), offset, value);
    return value;
}

uint16_t
SBData::GetUnsignedInt16 (lldb::SBError& error, lldb::offset_t offset)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    uint16_t value = 0;
    if (!m_opaque_sp.get())
    {
        error.SetErrorString("no value to read from");
    }
    else
    {
        uint32_t old_offset = offset;
        value = m_opaque_sp->GetU16(&offset);
        if (offset == old_offset)
            error.SetErrorString("unable to read data");
    }
    if (log)
        log->Printf ("SBData::GetUnsignedInt16 (error=%p,offset=%" PRIu64 ") => "
                     "(%hd)", error.get(), offset, value);
    return value;
}

uint32_t
SBData::GetUnsignedInt32 (lldb::SBError& error, lldb::offset_t offset)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    uint32_t value = 0;
    if (!m_opaque_sp.get())
    {
        error.SetErrorString("no value to read from");
    }
    else
    {
        uint32_t old_offset = offset;
        value = m_opaque_sp->GetU32(&offset);
        if (offset == old_offset)
            error.SetErrorString("unable to read data");
    }
    if (log)
        log->Printf ("SBData::GetUnsignedInt32 (error=%p,offset=%" PRIu64 ") => "
                     "(%d)", error.get(), offset, value);
    return value;
}

uint64_t
SBData::GetUnsignedInt64 (lldb::SBError& error, lldb::offset_t offset)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    uint64_t value = 0;
    if (!m_opaque_sp.get())
    {
        error.SetErrorString("no value to read from");
    }
    else
    {
        uint32_t old_offset = offset;
        value = m_opaque_sp->GetU64(&offset);
        if (offset == old_offset)
            error.SetErrorString("unable to read data");
    }
    if (log)
        log->Printf ("SBData::GetUnsignedInt64 (error=%p,offset=%" PRIu64 ") => "
                     "(%" PRId64 ")", error.get(), offset, value);
    return value;
}

int8_t
SBData::GetSignedInt8 (lldb::SBError& error, lldb::offset_t offset)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    int8_t value = 0;
    if (!m_opaque_sp.get())
    {
        error.SetErrorString("no value to read from");
    }
    else
    {
        uint32_t old_offset = offset;
        value = (int8_t)m_opaque_sp->GetMaxS64(&offset, 1);
        if (offset == old_offset)
            error.SetErrorString("unable to read data");
    }
    if (log)
        log->Printf ("SBData::GetSignedInt8 (error=%p,offset=%" PRIu64 ") => "
                     "(%c)", error.get(), offset, value);
    return value;
}

int16_t
SBData::GetSignedInt16 (lldb::SBError& error, lldb::offset_t offset)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    int16_t value = 0;
    if (!m_opaque_sp.get())
    {
        error.SetErrorString("no value to read from");
    }
    else
    {
        uint32_t old_offset = offset;
        value = (int16_t)m_opaque_sp->GetMaxS64(&offset, 2);
        if (offset == old_offset)
            error.SetErrorString("unable to read data");
    }
    if (log)
        log->Printf ("SBData::GetSignedInt16 (error=%p,offset=%" PRIu64 ") => "
                     "(%hd)", error.get(), offset, value);
    return value;
}

int32_t
SBData::GetSignedInt32 (lldb::SBError& error, lldb::offset_t offset)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    int32_t value = 0;
    if (!m_opaque_sp.get())
    {
        error.SetErrorString("no value to read from");
    }
    else
    {
        uint32_t old_offset = offset;
        value = (int32_t)m_opaque_sp->GetMaxS64(&offset, 4);
        if (offset == old_offset)
            error.SetErrorString("unable to read data");
    }
    if (log)
        log->Printf ("SBData::GetSignedInt32 (error=%p,offset=%" PRIu64 ") => "
                     "(%d)", error.get(), offset, value);
    return value;
}

int64_t
SBData::GetSignedInt64 (lldb::SBError& error, lldb::offset_t offset)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    int64_t value = 0;
    if (!m_opaque_sp.get())
    {
        error.SetErrorString("no value to read from");
    }
    else
    {
        uint32_t old_offset = offset;
        value = (int64_t)m_opaque_sp->GetMaxS64(&offset, 8);
        if (offset == old_offset)
            error.SetErrorString("unable to read data");
    }
    if (log)
        log->Printf ("SBData::GetSignedInt64 (error=%p,offset=%" PRIu64 ") => "
                     "(%" PRId64 ")", error.get(), offset, value);
    return value;
}

const char*
SBData::GetString (lldb::SBError& error, lldb::offset_t offset)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    const char* value = 0;
    if (!m_opaque_sp.get())
    {
        error.SetErrorString("no value to read from");
    }
    else
    {
        uint32_t old_offset = offset;
        value = m_opaque_sp->GetCStr(&offset);
        if (offset == old_offset || (value == NULL))
            error.SetErrorString("unable to read data");
    }
    if (log)
        log->Printf ("SBData::GetString (error=%p,offset=%" PRIu64 ") => "
                     "(%p)", error.get(), offset, value);
    return value;
}

bool
SBData::GetDescription (lldb::SBStream &description, lldb::addr_t base_addr)
{
    Stream &strm = description.ref();

    if (m_opaque_sp)
    {
        m_opaque_sp->Dump (&strm,
                           0,
                           lldb::eFormatBytesWithASCII,
                           1,
                           m_opaque_sp->GetByteSize(),
                           16,
                           base_addr,
                           0,
                           0);
    }
    else
        strm.PutCString ("No value");
    
    return true;
}

size_t
SBData::ReadRawData (lldb::SBError& error,
                     lldb::offset_t offset,
                     void *buf,
                     size_t size)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    void* ok = NULL;
    if (!m_opaque_sp.get())
    {
        error.SetErrorString("no value to read from");
    }
    else
    {
        uint32_t old_offset = offset;
        ok = m_opaque_sp->GetU8(&offset, buf, size);
        if ((offset == old_offset) || (ok == NULL))
            error.SetErrorString("unable to read data");
    }
    if (log)
        log->Printf ("SBData::ReadRawData (error=%p,offset=%" PRIu64 ",buf=%p,size=%lu) => "
                     "(%p)", error.get(), offset, buf, size, ok);
    return ok ? size : 0;
}

void
SBData::SetData (lldb::SBError& error,
                 const void *buf,
                 size_t size,
                 lldb::ByteOrder endian,
                 uint8_t addr_size)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (!m_opaque_sp.get())
        m_opaque_sp.reset(new DataExtractor(buf, size, endian, addr_size));
    else
        m_opaque_sp->SetData(buf, size, endian);
    if (log)
        log->Printf ("SBData::SetData (error=%p,buf=%p,size=%lu,endian=%d,addr_size=%c) => "
                     "(%p)", error.get(), buf, size, endian, addr_size, m_opaque_sp.get());
}

bool
SBData::Append (const SBData& rhs)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    bool value = false;
    if (m_opaque_sp.get() && rhs.m_opaque_sp.get())
        value = m_opaque_sp.get()->Append(*rhs.m_opaque_sp);
    if (log)
        log->Printf ("SBData::Append (rhs=%p) => "
                     "(%s)", rhs.get(), value ? "true" : "false");
    return value;
}

lldb::SBData
SBData::CreateDataFromCString (lldb::ByteOrder endian, uint32_t addr_byte_size, const char* data)
{
    if (!data || !data[0])
        return SBData();
    
    uint32_t data_len = strlen(data);
    
    lldb::DataBufferSP buffer_sp(new DataBufferHeap(data, data_len));
    lldb::DataExtractorSP data_sp(new DataExtractor(buffer_sp, endian, addr_byte_size));
    
    SBData ret(data_sp);
    
    return ret;
}

lldb::SBData
SBData::CreateDataFromUInt64Array (lldb::ByteOrder endian, uint32_t addr_byte_size, uint64_t* array, size_t array_len)
{
    if (!array || array_len == 0)
        return SBData();
    
    size_t data_len = array_len * sizeof(uint64_t);
    
    lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));
    lldb::DataExtractorSP data_sp(new DataExtractor(buffer_sp, endian, addr_byte_size));
    
    SBData ret(data_sp);
    
    return ret;
}

lldb::SBData
SBData::CreateDataFromUInt32Array (lldb::ByteOrder endian, uint32_t addr_byte_size, uint32_t* array, size_t array_len)
{
    if (!array || array_len == 0)
        return SBData();
    
    size_t data_len = array_len * sizeof(uint32_t);
    
    lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));
    lldb::DataExtractorSP data_sp(new DataExtractor(buffer_sp, endian, addr_byte_size));
    
    SBData ret(data_sp);
    
    return ret;
}

lldb::SBData
SBData::CreateDataFromSInt64Array (lldb::ByteOrder endian, uint32_t addr_byte_size, int64_t* array, size_t array_len)
{
    if (!array || array_len == 0)
        return SBData();
    
    size_t data_len = array_len * sizeof(int64_t);
    
    lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));
    lldb::DataExtractorSP data_sp(new DataExtractor(buffer_sp, endian, addr_byte_size));
    
    SBData ret(data_sp);
    
    return ret;
}

lldb::SBData
SBData::CreateDataFromSInt32Array (lldb::ByteOrder endian, uint32_t addr_byte_size, int32_t* array, size_t array_len)
{
    if (!array || array_len == 0)
        return SBData();
    
    size_t data_len = array_len * sizeof(int32_t);
    
    lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));
    lldb::DataExtractorSP data_sp(new DataExtractor(buffer_sp, endian, addr_byte_size));
    
    SBData ret(data_sp);
    
    return ret;
}

lldb::SBData
SBData::CreateDataFromDoubleArray (lldb::ByteOrder endian, uint32_t addr_byte_size, double* array, size_t array_len)
{
    if (!array || array_len == 0)
        return SBData();
    
    size_t data_len = array_len * sizeof(double);
    
    lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));
    lldb::DataExtractorSP data_sp(new DataExtractor(buffer_sp, endian, addr_byte_size));
    
    SBData ret(data_sp);
    
    return ret;
}

bool
SBData::SetDataFromCString (const char* data)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    
    if (!data)
    {
        if (log)
            log->Printf ("SBData::SetDataFromCString (data=%p) => "
                         "false", data);
        return false;
    }
    
    size_t data_len = strlen(data);
        
    lldb::DataBufferSP buffer_sp(new DataBufferHeap(data, data_len));
    
    if (!m_opaque_sp.get())
        m_opaque_sp.reset(new DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize()));
    else
        m_opaque_sp->SetData(buffer_sp);
    
    if (log)
        log->Printf ("SBData::SetDataFromCString (data=%p) => "
                     "true", data);
    
    return true;
}

bool
SBData::SetDataFromUInt64Array (uint64_t* array, size_t array_len)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    
    if (!array || array_len == 0)
    {
        if (log)
            log->Printf ("SBData::SetDataFromUInt64Array (array=%p, array_len = %lu) => "
                         "false", array, array_len);
        return false;
    }

    size_t data_len = array_len * sizeof(uint64_t);
    
    lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));
    
    if (!m_opaque_sp.get())
        m_opaque_sp.reset(new DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize()));
    else
        m_opaque_sp->SetData(buffer_sp);
    
    if (log)
        log->Printf ("SBData::SetDataFromUInt64Array (array=%p, array_len = %lu) => "
                     "true", array, array_len);
    
    return true;
}

bool
SBData::SetDataFromUInt32Array (uint32_t* array, size_t array_len)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    
    if (!array || array_len == 0)
    {
        if (log)
            log->Printf ("SBData::SetDataFromUInt32Array (array=%p, array_len = %lu) => "
                         "false", array, array_len);
        return false;
    }
    
    size_t data_len = array_len * sizeof(uint32_t);
    
    lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));
    
    if (!m_opaque_sp.get())
        m_opaque_sp.reset(new DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize()));
    else
        m_opaque_sp->SetData(buffer_sp);
    
    if (log)
        log->Printf ("SBData::SetDataFromUInt32Array (array=%p, array_len = %lu) => "
                     "true", array, array_len);
    
    return true;
}

bool
SBData::SetDataFromSInt64Array (int64_t* array, size_t array_len)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    
    if (!array || array_len == 0)
    {
        if (log)
            log->Printf ("SBData::SetDataFromSInt64Array (array=%p, array_len = %lu) => "
                         "false", array, array_len);
        return false;
    }
    
    size_t data_len = array_len * sizeof(int64_t);
    
    lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));
    
    if (!m_opaque_sp.get())
        m_opaque_sp.reset(new DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize()));
    else
        m_opaque_sp->SetData(buffer_sp);
    
    if (log)
        log->Printf ("SBData::SetDataFromSInt64Array (array=%p, array_len = %lu) => "
                     "true", array, array_len);
    
    return true;
}

bool
SBData::SetDataFromSInt32Array (int32_t* array, size_t array_len)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    
    if (!array || array_len == 0)
    {
        if (log)
            log->Printf ("SBData::SetDataFromSInt32Array (array=%p, array_len = %lu) => "
                         "false", array, array_len);
        return false;
    }
    
    size_t data_len = array_len * sizeof(int32_t);
    
    lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));
    
    if (!m_opaque_sp.get())
        m_opaque_sp.reset(new DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize()));
    else
        m_opaque_sp->SetData(buffer_sp);
    
    if (log)
        log->Printf ("SBData::SetDataFromSInt32Array (array=%p, array_len = %lu) => "
                     "true", array, array_len);
    
    return true;
}

bool
SBData::SetDataFromDoubleArray (double* array, size_t array_len)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    
    if (!array || array_len == 0)
    {
        if (log)
            log->Printf ("SBData::SetDataFromDoubleArray (array=%p, array_len = %lu) => "
                         "false", array, array_len);
        return false;
    }
    
    size_t data_len = array_len * sizeof(double);
    
    lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len));
    
    if (!m_opaque_sp.get())
        m_opaque_sp.reset(new DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize()));
    else
        m_opaque_sp->SetData(buffer_sp);
    
    if (log)
        log->Printf ("SBData::SetDataFromDoubleArray (array=%p, array_len = %lu) => "
                     "true", array, array_len);
    
    return true;
}
