#include <cmake_config.h>

#if defined(TANGO_MEMSET_S)
  #define __STDC_WANT_LIB_EXT1__ 1
#endif

#include <cstring>

#if defined(TANGO_SECURE_ZERO_MEMORY)
  #include <windows.h>
#endif

#include "SecureString.h"

#include <algorithm>

namespace
{
void safe_clear(void *ptr, size_t len)
{
#if defined(TANGO_EXPLICIT_BZERO)
    explicit_bzero(ptr, len);
#elif defined(TANGO_SECURE_ZERO_MEMORY)
    SecureZeroMemory(ptr, len);
#elif defined(TANGO_MEMSET_S)
    memset_s(ptr, len, 0, len);
#elif defined(TANGO_BZERO)
    bzero(ptr, len);
#else
  #error "Missing secure delete function, please file an issue and report your OS."
#endif
}
} // namespace

SecureString::SecureString(std::string &str)
{
    m_len = str.size() + 1;
    m_data = new char[m_len];

    std::copy(str.c_str(), str.c_str() + str.size(), m_data);
    m_data[m_len - 1] = '\0';

    if(!str.empty())
    {
        safe_clear(str.data(), str.size());
        str.clear();
    }
}

SecureString::~SecureString()
{
    safe_clear(m_data, m_len);
    delete[] m_data;
}

bool SecureString::empty() const
{
    return m_len == 1;
}

const char *SecureString::c_str() const
{
    return m_data;
}
