//===-- SBData.cpp ----------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/API/SBData.h"
#include "lldb/API/SBError.h"
#include "lldb/API/SBStream.h"

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

#include <cinttypes>
#include <memory>

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 () => "
                "( %" PRIu64 " )",
                (uint64_t)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)",
                static_cast<void *>(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)",
                static_cast<void *>(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)",
                static_cast<void *>(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)",
                static_cast<void *>(error.get()), offset,
                reinterpret_cast<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)",
                static_cast<void *>(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)",
                static_cast<void *>(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)",
                static_cast<void *>(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 ")",
                static_cast<void *>(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)",
                static_cast<void *>(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)",
                static_cast<void *>(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)",
                static_cast<void *>(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 ")",
                static_cast<void *>(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)",
                static_cast<void *>(error.get()), offset,
                static_cast<const void *>(value));
  return value;
}

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

  if (m_opaque_sp) {
    DumpDataExtractor(*m_opaque_sp, &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=%" PRIu64 ") => "
                "(%p)",
                static_cast<void *>(error.get()), offset,
                static_cast<void *>(buf), static_cast<uint64_t>(size),
                static_cast<void *>(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 = std::make_shared<DataExtractor>(buf, size, endian, addr_size);
  else
  {
    m_opaque_sp->SetData(buf, size, endian);
    m_opaque_sp->SetAddressByteSize(addr_size);
  }

  if (log)
    log->Printf("SBData::SetData (error=%p,buf=%p,size=%" PRIu64
                ",endian=%d,addr_size=%c) => "
                "(%p)",
                static_cast<void *>(error.get()),
                static_cast<const void *>(buf), static_cast<uint64_t>(size),
                endian, addr_size, static_cast<void *>(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)",
                static_cast<void *>(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",
                  static_cast<const void *>(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 = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(),
                                                  GetAddressByteSize());
  else
    m_opaque_sp->SetData(buffer_sp);

  if (log)
    log->Printf("SBData::SetDataFromCString (data=%p) => true",
                static_cast<const void *>(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 = %" PRIu64
          ") => "
          "false",
          static_cast<void *>(array), static_cast<uint64_t>(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 = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(),
                                                  GetAddressByteSize());
  else
    m_opaque_sp->SetData(buffer_sp);

  if (log)
    log->Printf("SBData::SetDataFromUInt64Array (array=%p, array_len = %" PRIu64
                ") => "
                "true",
                static_cast<void *>(array), static_cast<uint64_t>(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 = %" PRIu64
          ") => "
          "false",
          static_cast<void *>(array), static_cast<uint64_t>(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 = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(),
                                                  GetAddressByteSize());
  else
    m_opaque_sp->SetData(buffer_sp);

  if (log)
    log->Printf("SBData::SetDataFromUInt32Array (array=%p, array_len = %" PRIu64
                ") => "
                "true",
                static_cast<void *>(array), static_cast<uint64_t>(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 = %" PRIu64
          ") => "
          "false",
          static_cast<void *>(array), static_cast<uint64_t>(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 = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(),
                                                  GetAddressByteSize());
  else
    m_opaque_sp->SetData(buffer_sp);

  if (log)
    log->Printf("SBData::SetDataFromSInt64Array (array=%p, array_len = %" PRIu64
                ") => "
                "true",
                static_cast<void *>(array), static_cast<uint64_t>(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 = %" PRIu64
          ") => "
          "false",
          static_cast<void *>(array), static_cast<uint64_t>(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 = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(),
                                                  GetAddressByteSize());
  else
    m_opaque_sp->SetData(buffer_sp);

  if (log)
    log->Printf("SBData::SetDataFromSInt32Array (array=%p, array_len = %" PRIu64
                ") => "
                "true",
                static_cast<void *>(array), static_cast<uint64_t>(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 = %" PRIu64
          ") => "
          "false",
          static_cast<void *>(array), static_cast<uint64_t>(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 = std::make_shared<DataExtractor>(buffer_sp, GetByteOrder(),
                                                  GetAddressByteSize());
  else
    m_opaque_sp->SetData(buffer_sp);

  if (log)
    log->Printf("SBData::SetDataFromDoubleArray (array=%p, array_len = %" PRIu64
                ") => "
                "true",
                static_cast<void *>(array), static_cast<uint64_t>(array_len));

  return true;
}
