//===-- 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 <inttypes.h> // PRIu64

#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 () => "
                "( %" 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) {
    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=%" 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.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=%" 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.reset(
        new 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.reset(
        new 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.reset(
        new 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.reset(
        new 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.reset(
        new 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.reset(
        new 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;
}
