//===-- ConstString.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/Core/ConstString.h"
#include "lldb/Core/Stream.h"
#include "lldb/Host/Mutex.h"
#include "llvm/ADT/StringMap.h"

using namespace lldb_private;


class Pool
{
public:
    typedef const char * StringPoolValueType;
    typedef llvm::StringMap<StringPoolValueType, llvm::BumpPtrAllocator> StringPool;
    typedef llvm::StringMapEntry<StringPoolValueType> StringPoolEntryType;
    
    //------------------------------------------------------------------
    // Default constructor
    //
    // Initialize the member variables and create the empty string.
    //------------------------------------------------------------------
    Pool () :
        m_mutex (Mutex::eMutexTypeRecursive),
        m_string_map ()
    {
    }

    //------------------------------------------------------------------
    // Destructor
    //------------------------------------------------------------------
    ~Pool ()
    {
    }


    static StringPoolEntryType &
    GetStringMapEntryFromKeyData (const char *keyData)
    {
        char *ptr = const_cast<char*>(keyData) - sizeof (StringPoolEntryType);
        return *reinterpret_cast<StringPoolEntryType*>(ptr);
    }

    size_t
    GetConstCStringLength (const char *ccstr) const
    {
        if (ccstr)
        {
            const StringPoolEntryType&entry = GetStringMapEntryFromKeyData (ccstr);
            return entry.getKey().size();
        }
        return 0;
    }

    StringPoolValueType
    GetMangledCounterpart (const char *ccstr) const
    {
        if (ccstr)
            return GetStringMapEntryFromKeyData (ccstr).getValue();
        return 0;
    }

    bool
    SetMangledCounterparts (const char *key_ccstr, const char *value_ccstr)
    {
        if (key_ccstr && value_ccstr)
        {
            GetStringMapEntryFromKeyData (key_ccstr).setValue(value_ccstr);
            GetStringMapEntryFromKeyData (value_ccstr).setValue(key_ccstr);
            return true;
        }
        return false;
    }

    const char *
    GetConstCString (const char *cstr)
    {
        if (cstr)
            return GetConstCStringWithLength (cstr, strlen (cstr));
        return NULL;
    }

    const char *
    GetConstCStringWithLength (const char *cstr, size_t cstr_len)
    {
        if (cstr)
        {
            Mutex::Locker locker (m_mutex);
            llvm::StringRef string_ref (cstr, cstr_len);
            StringPoolEntryType& entry = m_string_map.GetOrCreateValue (string_ref, (StringPoolValueType)NULL);
            return entry.getKeyData();
        }
        return NULL;
    }

    const char *
    GetConstCStringWithStringRef (const llvm::StringRef &string_ref)
    {
        if (string_ref.data())
        {
            Mutex::Locker locker (m_mutex);
            StringPoolEntryType& entry = m_string_map.GetOrCreateValue (string_ref, (StringPoolValueType)NULL);
            return entry.getKeyData();
        }
        return NULL;
    }

    const char *
    GetConstCStringAndSetMangledCounterPart (const char *demangled_cstr, const char *mangled_ccstr)
    {
        if (demangled_cstr)
        {
            Mutex::Locker locker (m_mutex);
            // Make string pool entry with the mangled counterpart already set
            StringPoolEntryType& entry = m_string_map.GetOrCreateValue (llvm::StringRef (demangled_cstr), mangled_ccstr);

            // Extract the const version of the demangled_cstr
            const char *demangled_ccstr = entry.getKeyData();
            // Now assign the demangled const string as the counterpart of the
            // mangled const string...
            GetStringMapEntryFromKeyData (mangled_ccstr).setValue(demangled_ccstr);
            // Return the constant demangled C string
            return demangled_ccstr;
        }
        return NULL;
    }

    const char *
    GetConstTrimmedCStringWithLength (const char *cstr, size_t cstr_len)
    {
        if (cstr)
        {
            const size_t trimmed_len = std::min<size_t> (strlen (cstr), cstr_len);
            return GetConstCStringWithLength (cstr, trimmed_len);
        }
        return NULL;
    }

    //------------------------------------------------------------------
    // Return the size in bytes that this object and any items in its
    // collection of uniqued strings + data count values takes in
    // memory.
    //------------------------------------------------------------------
    size_t
    MemorySize() const
    {
        Mutex::Locker locker (m_mutex);
        size_t mem_size = sizeof(Pool);
        const_iterator end = m_string_map.end();
        for (const_iterator pos = m_string_map.begin(); pos != end; ++pos)
        {
            mem_size += sizeof(StringPoolEntryType) + pos->getKey().size();
        }
        return mem_size;
    }

protected:
    //------------------------------------------------------------------
    // Typedefs
    //------------------------------------------------------------------
    typedef StringPool::iterator iterator;
    typedef StringPool::const_iterator const_iterator;

    //------------------------------------------------------------------
    // Member variables
    //------------------------------------------------------------------
    mutable Mutex m_mutex;
    StringPool m_string_map;
};

//----------------------------------------------------------------------
// Frameworks and dylibs aren't supposed to have global C++
// initializers so we hide the string pool in a static function so
// that it will get initialized on the first call to this static
// function.
//
// Note, for now we make the string pool a pointer to the pool, because
// we can't guarantee that some objects won't get destroyed after the
// global destructor chain is run, and trying to make sure no destructors
// touch ConstStrings is difficult.  So we leak the pool instead.
//
// FIXME: If we are going to keep it this way we should come up with some
// abstraction to "pthread_once" so we don't have to check the pointer
// every time.
//----------------------------------------------------------------------
static Pool &
StringPool()
{
    static Mutex g_pool_initialization_mutex;
    static Pool *g_string_pool = NULL;

    if (g_string_pool == NULL)
    {
        Mutex::Locker initialization_locker(g_pool_initialization_mutex);
        if (g_string_pool == NULL)
        {
            g_string_pool = new Pool();
        }
    }
    
    return *g_string_pool;
}

ConstString::ConstString (const char *cstr) :
    m_string (StringPool().GetConstCString (cstr))
{
}

ConstString::ConstString (const char *cstr, size_t cstr_len) :
    m_string (StringPool().GetConstCStringWithLength (cstr, cstr_len))
{
}

ConstString::ConstString (const llvm::StringRef &s) :
    m_string (StringPool().GetConstCStringWithLength (s.data(), s.size()))
{
}

bool
ConstString::operator < (const ConstString& rhs) const
{
    if (m_string == rhs.m_string)
        return false;

    llvm::StringRef lhs_string_ref (m_string, StringPool().GetConstCStringLength (m_string));
    llvm::StringRef rhs_string_ref (rhs.m_string, StringPool().GetConstCStringLength (rhs.m_string));

    // If both have valid C strings, then return the comparison
    if (lhs_string_ref.data() && rhs_string_ref.data())
        return lhs_string_ref < rhs_string_ref;

    // Else one of them was NULL, so if LHS is NULL then it is less than
    return lhs_string_ref.data() == NULL;
}

Stream&
lldb_private::operator << (Stream& s, const ConstString& str)
{
    const char *cstr = str.GetCString();
    if (cstr)
        s << cstr;

    return s;
}

size_t
ConstString::GetLength () const
{
    return StringPool().GetConstCStringLength (m_string);
}

int
ConstString::Compare (const ConstString& lhs, const ConstString& rhs)
{
    // If the iterators are the same, this is the same string
    register const char *lhs_cstr = lhs.m_string;
    register const char *rhs_cstr = rhs.m_string;
    if (lhs_cstr == rhs_cstr)
        return 0;
    if (lhs_cstr && rhs_cstr)
    {
        llvm::StringRef lhs_string_ref (lhs_cstr, StringPool().GetConstCStringLength (lhs_cstr));
        llvm::StringRef rhs_string_ref (rhs_cstr, StringPool().GetConstCStringLength (rhs_cstr));
        return lhs_string_ref.compare(rhs_string_ref);
    }

    if (lhs_cstr)
        return +1;  // LHS isn't NULL but RHS is
    else
        return -1;  // LHS is NULL but RHS isn't
}

void
ConstString::Dump(Stream *s, const char *fail_value) const
{
    if (s)
    {
        const char *cstr = AsCString (fail_value);
        if (cstr)
            s->PutCString (cstr);
    }
}

void
ConstString::DumpDebug(Stream *s) const
{
    const char *cstr = GetCString ();
    size_t cstr_len = GetLength();
    // Only print the parens if we have a non-NULL string
    const char *parens = cstr ? "\"" : "";
    s->Printf("%*p: ConstString, string = %s%s%s, length = %" PRIu64, (int)sizeof(void*) * 2, this, parens, cstr, parens, (uint64_t)cstr_len);
}

void
ConstString::SetCString (const char *cstr)
{
    m_string = StringPool().GetConstCString (cstr);
}

void
ConstString::SetString (const llvm::StringRef &s)
{
    m_string = StringPool().GetConstCStringWithLength (s.data(), s.size());
}

void
ConstString::SetCStringWithMangledCounterpart (const char *demangled, const ConstString &mangled)
{
    m_string = StringPool().GetConstCStringAndSetMangledCounterPart (demangled, mangled.m_string);
}

bool
ConstString::GetMangledCounterpart (ConstString &counterpart) const
{
    counterpart.m_string = StringPool().GetMangledCounterpart(m_string);
    return counterpart;
}

void
ConstString::SetCStringWithLength (const char *cstr, size_t cstr_len)
{
    m_string = StringPool().GetConstCStringWithLength(cstr, cstr_len);
}

void
ConstString::SetTrimmedCStringWithLength (const char *cstr, size_t cstr_len)
{
    m_string = StringPool().GetConstTrimmedCStringWithLength (cstr, cstr_len);
}

size_t
ConstString::StaticMemorySize()
{
    // Get the size of the static string pool
    return StringPool().MemorySize();
}
