/*
 * Copyright (C) 2009 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <string>
#include <algorithm>
#include <climits>
#include <cstddef>
#include <cstring>
#include <malloc.h>
#include <ostream>

#ifndef MAX_SIZE_T
#define MAX_SIZE_T           (~(size_t)0)
#endif

namespace {
char kEmptyString[1] = { '\0' };
// Dummy char used in the 'at' accessor when the index is out of
// range.
char sDummy;
}

namespace std {
// Implementation of the std::string class.
//
// mData points either to a heap allocated array of bytes or the constant
// kEmptyString when empty and reserve has not been called.
//
// The size of the buffer pointed by mData is mCapacity + 1.
// The extra byte is need to store the '\0'.
//
// mCapacity is either mLength or the number of bytes reserved using
// reserve(int)).
//
// mLength is the number of char in the string, excluding the terminating '\0'.
//
// TODO: replace the overflow checks with some better named macros.
//
// Allocate n + 1 number of bytes for the string. Update mCapacity.
// Ensure that mCapacity + 1 and mLength + 1 is accessible.
// In case of error the original state of the string is restored.
// @param n Number of bytes requested. String allocate n + 1 to hold
//            the terminating '\0'.
// @return true if the buffer could be allocated, false otherwise.
bool string::SafeMalloc(size_type n)
{
    // Not empty and no overflow
    if (n > 0 && n + 1 > n)
    {
        value_type *oldData = mData;

        mData = static_cast<value_type *>(::malloc(n + 1));
        if (NULL != mData)
        {
            mCapacity = n;
            return true;
        }
        mData = oldData;  // roll back
    }
    return false;
}

// Resize the buffer pointed by mData if n >= mLength.
// mData points to an allocated buffer or the empty string.
// @param n The number of bytes for the internal buffer.
//            Must be > mLength and > 0.
void string::SafeRealloc(size_type n)
{
    // truncation or nothing to do or n too big (overflow)
    if (n < mLength || n == mCapacity || n + 1 < n) {
        return;
    }

    if (kEmptyString == mData)
    {
        if (SafeMalloc(n)) {
            *mData = '\0';
        }
        return;
    }

    value_type *oldData = mData;

    mData = static_cast<char*>(::realloc(mData, n + 1));
    if (NULL == mData) // reallocate failed.
    {
        mData = oldData;
    }
    else
    {
        mCapacity = n;
    }
}

void string::SafeFree(value_type *buffer)
{
    if (buffer != kEmptyString)
    {
        ::free(buffer);
    }
}

// If the memory is on the heap, release it. Do nothing we we point at the empty
// string. On return mData points to str.
void string::ResetTo(value_type *str)
{
    SafeFree(mData);
    mData = str;
}

void string::ConstructEmptyString()
{
    mData = kEmptyString;
    mLength = 0;
    mCapacity = 0;
}

void string::Constructor(const value_type *str, size_type n)
{
    Constructor(str, 0, n);
}


void string::Constructor(const value_type *str, size_type pos, size_type n)
{
    // Enough data and no overflow
    if (SafeMalloc(n))
    {
        memcpy(mData, str + pos, n);
        mLength = n;
        mData[mLength] = '\0';
        return;  // Success
    }
    ConstructEmptyString();
}

void string::Constructor(size_type n, char c)
{
    // Enough data and no overflow

    if (SafeMalloc(n))
    {
        memset(mData, c, n);
        mLength = n;
        mData[mLength] = '\0';
        return;  // Success
    }
    ConstructEmptyString();
}

string::string()
{
    ConstructEmptyString();
}

string::string(const string& str)
{
    Constructor(str.mData, str.mLength);
}

string::string(const string& str, size_type pos, size_type n)
{
    if (pos < str.mLength)
    {
        if (n > (str.mLength - pos)) {
            n = str.mLength - pos;
        }
        Constructor(str.mData + pos , n);
    }
    else
    {
        ConstructEmptyString();
    }
}

string::string(const string& str, size_type pos)
{
    if (pos < str.mLength)
    {
        Constructor(str.mData, pos, str.mLength - pos);
    }
    else
    {
        ConstructEmptyString();
    }
}

string::string(const value_type *str)
{
    if (NULL != str)
    {
        Constructor(str, traits_type::length(str));
    }
    else
    {
        ConstructEmptyString();
    }
}

string::string(const value_type *str, size_type n)
{
    Constructor(str, n);
}

// Char repeat constructor.
string::string(size_type n, char c)
{
    Constructor(n, c);
}

string::string(const value_type *begin, const value_type *end)
{
    if (begin < end)
    {
        Constructor(begin, end - begin);
    }
    else
    {
        ConstructEmptyString();
    }
}

string::~string()
{
    clear();  // non virtual, ok to call.
}

void string::clear()
{
    mCapacity = 0;
    mLength = 0;
    ResetTo(kEmptyString);
}

string& string::erase(size_type pos, size_type n)
{
    if (pos >= mLength || 0 == n)
    {
        return *this;
    }
    // start of the characters left which need to be moved down.
    const size_t remainder = pos + n;

    // Truncate, even if there is an overflow.
    if (remainder >= mLength || remainder < pos)
    {
        *(mData + pos) = '\0';
        mLength = pos;
        return *this;
    }
    // remainder < mLength and allocation guarantees to be at least
    // mLength + 1
    size_t left = mLength - remainder + 1;
    value_type *d = mData + pos;
    value_type *s = mData + remainder;
    memmove(d, s, left);
    mLength -= n;
    return *this;
}

void string::Append(const value_type *str, size_type n)
{
    const size_type total_len = mLength + n;

    // n > 0 and no overflow for the string length + terminating null.
    if (n > 0 && (total_len + 1) > mLength)
    {
        if (total_len > mCapacity)
        {
            reserve(total_len);
            if (total_len > mCapacity)
            {  // something went wrong in the reserve call.
                return;
            }
        }
        memcpy(mData + mLength, str, n);
        mLength = total_len;
        mData[mLength] = '\0';
    }
}

string& string::append(const value_type *str)
{
    if (NULL != str)
    {
        Append(str, traits_type::length(str));
    }
    return *this;
}

string& string::append(const value_type *str, size_type n)
{
    if (NULL != str)
    {
        Append(str, n);
    }
    return *this;
}

string& string::append(const value_type *str, size_type pos, size_type n)
{
    if (NULL != str)
    {
        Append(str + pos, n);
    }
    return *this;
}

string& string::append(const string& str)
{
    Append(str.mData, str.mLength);
    return *this;
}

void string::push_back(const char c)
{
    // Check we don't overflow.
    if (mLength + 2 > mLength)
    {
        const size_type total_len = mLength + 1;

        if (total_len > mCapacity)
        {
            reserve(total_len);
            if (total_len > mCapacity)
            {  // something went wrong in the reserve call.
                return;
            }
        }
        *(mData + mLength) = c;
        ++mLength;
        mData[mLength] = '\0';
    }
}


int string::compare(const string& other) const
{
    if (this == &other)
    {
        return 0;
    }
    else if (mLength == other.mLength)
    {
        return memcmp(mData, other.mData, mLength);
    }
    else
    {
        return mLength < other.mLength ? -1 : 1;
    }
}

int string::compare(const value_type *other) const
{
    if (NULL == other)
    {
        return 1;
    }
    return strcmp(mData, other);
}

bool operator==(const string& left, const string& right)
{
    if (&left == &right) {
        return true;
    }
    return (left.size() == right.size() &&
            !char_traits<char>::compare(left.mData, right.mData, left.size()));
}

bool operator==(const string& left, const string::value_type *right)
{
    if (NULL == right) {
        return false;
    }
    // We can use strcmp here because even when the string is build from an
    // array of char we insert the terminating '\0'.
    return std::strcmp(left.mData, right) == 0;
}

void string::reserve(size_type size)
{
    if (0 == size)
    {
        if (0 == mCapacity)
        {
            return;
        }
        else if (0 == mLength)
        {  // Shrink to fit an empty string.
            mCapacity = 0;
            ResetTo(kEmptyString);
        }
        else
        {  // Shrink to fit a non empty string
            SafeRealloc(mLength);
        }
    }
    else if (size > mLength)
    {
        SafeRealloc(size);
    }
}

void string::swap(string& other)
{
    if (this == &other) return;
    value_type *const tmp_mData = mData;
    const size_type tmp_mCapacity = mCapacity;
    const size_type tmp_mLength = mLength;

    mData = other.mData;
    mCapacity = other.mCapacity;
    mLength = other.mLength;

    other.mData = tmp_mData;
    other.mCapacity = tmp_mCapacity;
    other.mLength = tmp_mLength;
}

const char& string::operator[](const size_type pos) const
{
    return mData[pos];
}

char& string::operator[](const size_type pos)
{
    return mData[pos];
}

const char& string::at(const size_type pos) const
{
    if (pos < mLength) {
        return mData[pos];
    } else {
        sDummy = 'X';
        return sDummy;
    }
}

char& string::at(const size_type pos)
{
    if (pos < mLength) {
        return mData[pos];
    } else {
        sDummy = 'X';
        return sDummy;
    }
}

string& string::assign(const string& str)
{
    clear();
    Constructor(str.mData, str.mLength);
    return *this;
}

string& string::assign(const string& str, size_type pos, size_type n)
{
    if (pos >= str.mLength)
    {  // pos is out of bound
        return *this;
    }
    if (n <= str.mLength - pos)
    {
        clear();
        Constructor(str.mData, pos, n);
    }
    return *this;
}

string& string::assign(const value_type *str)
{
    if (NULL == str)
    {
        return *this;
    }
    clear();
    Constructor(str, traits_type::length(str));
    return *this;
}

string& string::assign(const value_type *array, size_type n)
{
    if (NULL == array || 0 == n)
    {
        return *this;
    }
    clear();
    Constructor(array, n);
    return *this;
}

string& string::operator=(char c)
{
    clear();
    Constructor(1, c);
    return *this;
}

string::size_type string::find(const value_type *str, size_type pos) const
{

    if (NULL == str)
    {
        return string::npos;
    }

    // Empty string is found everywhere except beyond the end. It is
    // possible to find the empty string right after the last char,
    // hence we used mLength and not mLength - 1 in the comparison.
    if (*str == '\0')
    {
        return pos > mLength ? string::npos : pos;
    }

    if (mLength == 0 || pos > mLength - 1)
    {
        return string::npos;
    }

    value_type *idx = std::strstr(mData + pos, str);

    if (NULL == idx)
    {
        return string::npos;
    }

    const std::ptrdiff_t delta = idx - mData;

    return static_cast<size_type>(delta);
}

string string::substr(size_type pos, size_type n) const {
    return string(*this, pos, n);
}

string::size_type string::find_first_of(value_type c, size_type pos) const {
    if (pos >= mLength) {
        return npos;
    }
    const char *res;
    // The last parameter represents a number of chars, not a index.
    res = static_cast<const char *>(std::memchr(mData + pos, c, mLength - pos));
    return res != NULL ? res - mData : npos;
}

string::size_type string::find_last_of(value_type c, size_type pos) const {
    if (mLength == 0) {
        return npos;
    } else if (pos >= mLength) {
        pos = mLength - 1;  // >= 0
    }

    const char *res;
    // Note:memrchr is not in the std namepace.
    // The last parameter represents a number of chars, not a index.
    res = static_cast<const char *>(memrchr(mData, c, pos + 1));
    return res != NULL ? res - mData : npos;
}

string::size_type string::find_first_not_of(value_type c, size_type pos) const {
    char *curr = mData + pos;
    for (size_type i = pos; i < mLength; ++i, ++curr) {
        if (c != *curr) {
            return i;
        }
    }
    return npos;
}

string::size_type string::find_last_not_of(value_type c, size_type pos) const {
    if (mLength == 0) {
        return npos;
    } else if (pos >= mLength) {
        pos = mLength - 1;  // >= 0
    }

    char *curr = mData + pos;
    size_type i = pos;

    for (;; --i, --curr) {
        if (c != *curr) {
            return i;
        } else if (i == 0) {
            return npos;
        }
    }
}

bool operator<(const string& lhs, const string& rhs) {
    return lhs.compare(rhs) < 0;
}

bool operator<=(const string& lhs, const string& rhs) {
    return lhs.compare(rhs) <= 0;
}

bool operator>(const string& lhs, const string& rhs) {
    return lhs.compare(rhs) > 0;
}

bool operator>=(const string& lhs, const string& rhs) {
    return lhs.compare(rhs) >= 0;
}

void swap(string& lhs, string& rhs) {
    lhs.swap(rhs);
}

ostream& operator<<(ostream& os, const string& str) {
    return os.write_formatted(str.data(), str.size());
}

}  // namespace std
