#ifndef _CVSSTRING_H_
#define _CVSSTRING_H_

//
//  Thin wrapper around a char* string.
//  Allocates exactly as much space as is needed.
//

class CvsString
{
public:
    void requireSize(int);
protected:
    void resize(int);
    static void recycle(char*,int);
public:
    int strlen() const { return ::strlen(m_sBuffer); }
    void strcpy(const char*);
    void strncpy(const char*,int);
    void strcat(const char*);
public:
    // Assignable access to characters within the string.
    // An index outside the string returns a reference to a junk character.
    char& operator[] (int i) {
        if ((i < 0) || ((int)strlen() <= i)) { static char c; return c; }
        return m_sBuffer[i];
    }
public:
    CvsString& operator = (const char* s) { strcpy(s); return *this; }
    CvsString& operator = (const CvsString& s) { strcpy(s); return *this; }
    CvsString& operator += (const char* s) { strcat(s); return *this; }
    CvsString operator + (const char* s) const { CvsString v(m_sBuffer); v.strcat(s); return v; }
public:
    int operator == (const char* s) const { return 0 == strcmp(m_sBuffer,s); }
public:
    operator const char*() const { return m_sBuffer; }
public:
    int   getBufferMax() const { return m_cbBufferMax; }
    char* getBuffer()    { return m_sBuffer; }
public:
    CvsString() : m_sBuffer(0), m_cbBufferMax(0) { strcpy(""); }
    CvsString(const char* s) : m_sBuffer(0), m_cbBufferMax(0) { strcpy(s); }
    CvsString(const CvsString& s) : m_sBuffer(0), m_cbBufferMax(0) { strcpy(s); }
    ~CvsString();
protected:
    char* m_sBuffer;
    int   m_cbBufferMax;
};

//
//  Upsize the string buffer to at least the given size.
//

inline void CvsString::requireSize(int cbNew)
{
    if (m_cbBufferMax < cbNew) {
        resize(cbNew);
    }
}

//
//  Copy the given string into this string.
//

inline void CvsString::strcpy(const char* s)
{
    requireSize(::strlen(s)+1);
    ::strcpy(m_sBuffer,s);
}

//
//  Copy the given string into this string.
//

inline void CvsString::strncpy(const char* s,int n)
{
    requireSize(n+1);
    ::strncpy(m_sBuffer,s,n);
    m_sBuffer[n] = 0;
}

//
//  Concatenate the given string onto this string.
//

inline void CvsString::strcat(const char* s)
{
    requireSize(strlen()+::strlen(s)+1);
    ::strcat(m_sBuffer,s);
}

#endif
