// Copyright 2014 The Android Open Source Project
//
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

#ifndef ANDROID_BASE_STRING_H
#define ANDROID_BASE_STRING_H

#include <stddef.h>

namespace android {
namespace base {

class StringView;

// Custom string implementation:
// - Not a template, hence much better compiler error messages.
// - Uses short-string-optimization on all platforms.
// - No iterators (for now).
class String {
public:
    // Empty constructor.
    String();

    // Regular constructor from a C string.
    String(const char* string);

    // Copy constructor.
    String(const String& other);

    // Constructor from a StringView.
    explicit String(const StringView& other);

    // Constructor from a sized C string.
    String(const char* str, size_t len);

    // Fill-constructor.
    String(size_t count, char fill);

    // Destructor.
    ~String();

    // Return string as a zero-terminated C string.
    const char* c_str() const { return mStr; }

    void* data() { return mStr; }

    const void* data() const { return mStr; }

    // Return size of string in bytes, not including terminating zero.
    size_t size() const { return mSize; }

    // Return true if the string is empty, i.e. its size is 0.
    // Note that a non-empty string can embed 0 bytes.
    bool empty() const { return mSize == 0; }

    // Return current capacity.
    size_t capacity() const {
        return (mStr == mStorage) ? kMinCapacity : mCapacity;
    }

    // Array indexing operators.
    char& operator[](size_t index) { return mStr[index]; }
    const char& operator[](size_t index) const { return mStr[index]; }

    // Assign new values to strings.
    String& assign(const char* str);
    String& assign(const char* str, size_t len);
    String& assign(const String& other);
    String& assign(const StringView& other);
    String& assign(size_t count, char fill);
    String& assign(char ch);

    // Assignment operators.
    String& operator=(const char* str) {
        return this->assign(str);
    }

    String& operator=(const String& other) {
        return this->assign(other);
    }

    String& operator=(const StringView& other) {
        return this->assign(other);
    }

    String& operator=(char ch) {
        return this->assign(ch);
    }

    // Append new values to current string.
    String& append(const char* str);
    String& append(const char* str, size_t len);
    String& append(const String& other);
    String& append(const StringView& other);
    String& append(char ch);

    // Addition-Assignment operators.
    String& operator+=(const char* str) {
        return this->append(str);
    }

    String& operator+=(const String& other) {
        return this->append(other);
    }

    String& operator+=(const StringView& other) {
        return this->append(other);
    }

    String& operator+=(char ch) {
        return this->append(ch);
    }

    // Resize to a new size.
    void resize(size_t newSize);

    // Reserve enough room for |newSize| characters, followed by a
    // terminating zero.
    void reserve(size_t newSize);

    // Compare to something, return -1, 0 or +1 based on byte values.
    int compare(const char* str, size_t len) const;
    int compare(const char* str) const;
    int compare(const String& other) const;
    int compare(const StringView& other) const;
    int compare(char ch) const;

    // Compare for equality.
    bool equals(const char* str, size_t len) const;
    bool equals(const char* str) const;
    bool equals(const String& other) const;
    bool equals(const StringView& other) const;
    bool equals(char ch) const;

    // Binary operators.
    bool operator==(const char* str) const {
        return equals(str);
    }

    bool operator==(const String& other) const {
        return equals(other);
    }

    bool operator==(const StringView& other) const {
        return equals(other);
    }

    bool operator==(char ch) const {
        return equals(ch);
    }

    bool operator!=(const char* str) const {
        return !operator==(str);
    }

    bool operator!=(const String& other) const {
        return !operator==(other);
    }

    bool operator!=(const StringView& other) const {
        return !operator==(other);
    }

    bool operator!=(char ch) const {
        return !operator==(ch);
    }

    // Swap the content of this string with another one.
    void swap(String* other);

protected:
    friend class StringVector;

    // Internal helper routine to be used when |count| strings objects
    // have been moved or copied from |fromStrings| to |toStrings|.
    // This adjusts any internal |mStr| pointer to |mStorage| to the
    // new appropriate region. Used by StringVector to implement
    // optimized insert/copy/remove operations.
    static void adjustMovedSlice(String* fromStrings,
                                 String* toStrings,
                                 size_t count);

    // Move |count| strings from |strings + from| to |strings + to|
    // in memory. Used by StringVector to implement insert/delete
    // operations.
    static void moveSlice(String* strings,
                          size_t from,
                          size_t to,
                          size_t count);

    // Finalize |count| String instances from |strings|.
    // Used by StringVector to implement resize/reserve operations.
    static void finalizeSlice(String* strings, size_t count);

    // Minimum capacity for the in-object storage array |mStorage|,
    // not including the terminating zero. With a value of 16,
    // each String instance is 24 bytes on a 32-bit system, and
    // 32-bytes on a 64-bit one.
    enum {
        kMinCapacity = 15
    };

    char* mStr;
    size_t mSize;
    union {
        size_t mCapacity;
        char mStorage[kMinCapacity + 1U];
    };
};

}  // namespace base
}  // namespace android

#endif  // ANDROID_BASE_STRING_H
