// @topic T060m10d25x20 class DString -- using dynamic array of characters
// @brief class DString implementation

// DString.cpp
#include "DString.h"

DString::DString()
    :
    m_array( nullptr ),
    m_length( 0 ),
    m_capacity( INITIAL_CAPACITY )
{
    allocate( INITIAL_CAPACITY );
}//DString::DString


DString::DString(char const* pstr)
    :
    m_array(nullptr),
    m_length( strlen( pstr ) ),
    m_capacity(INITIAL_CAPACITY)
{
    allocate(m_length);
    strcpy(m_array, pstr);
}//DString::DString


// in a non-destructive manner
// allocate block of characters of the requested size
void DString::allocate( size_t capacity )
{
    if ( capacity < m_capacity ) return;
    char* new_block = new char[ capacity ];
    if ( m_array != nullptr ) {
        // copy the existing content to the new block:
        for ( size_t idx = 0; idx < m_length; ++idx ) {
            new_block[idx] = m_array[idx];
        }
        delete[] m_array; // free old block of characters
    }
    m_array = new_block; // remember new block of characters
    m_capacity = capacity;
}//DString::allocate


size_t DString::length() const
{
    return m_length;
}//DString::length


size_t DString::capacity() const
{
    return m_capacity;
}//DString::capacity


std::ostream& operator<<(std::ostream& cout, DString const& str)
{
    for (size_t idx = 0; idx < str.length(); ++idx ) {
        cout << str.m_array[idx];
    }
    return cout;
}//operator<<


std::istream& operator>>(std::istream& cin, DString& str)
{
    str.m_length = 0;
    while ( cin ) {
        int ch = cin.get(); // extract a single character form cin
        if ( ch == '\n' ) break;
        // before storing a character, check the capacity:
        if (str.m_length >= str.m_capacity) {
            str.allocate( str.m_capacity*2 );
        }
        str.m_array[str.m_length] = ch;
        ++str.m_length;
    }
    return cin;
}//operator>>