/* ----------------------------------------------------------------------- *//**
 *
 * @file OutputStreamBufferBase_impl.hpp
 *
 *//* ----------------------------------------------------------------------- */

#ifndef MADLIB_DBAL_OUTPUTSTREAMBUFFERBASE_IMPL_HPP
#define MADLIB_DBAL_OUTPUTSTREAMBUFFERBASE_IMPL_HPP

#include <cstring>      // Needed for std::memcpy

namespace madlib {

namespace dbal {

/**
 * @internal One extra byte is allocated for the terminating null character.
 */
template <class Derived, typename C, class Allocator>
OutputStreamBufferBase<Derived, C, Allocator>::OutputStreamBufferBase()
 :  mAllocator(), mStorageSize(kInitialBufferSize),
    mStorage(mAllocator.allocate(mStorageSize + 1)) {

    this->setp(mStorage, mStorage + mStorageSize);
}

template <class Derived, typename C, class Allocator>
OutputStreamBufferBase<Derived, C, Allocator>::~OutputStreamBufferBase() {
    mAllocator.deallocate(mStorage, mStorageSize + 1);
}

/**
 * @brief Output a string
 *
 * Subclasses are required to implement this method and to feed the message
 * to the DBMS-specific logging routine.
 * @param inMsg Null-terminated string to be output.
 * @param inLength Length of inMsg (for convenience).
 */
template <class Derived, typename C, class Allocator>
void
OutputStreamBufferBase<Derived, C, Allocator>::output(C* inMsg,
    std::size_t inLength) const {

    static_cast<const Derived*>(this)->output(inMsg, inLength);
}

/**
 * @brief Handle case when stream receives a character that does not fit
 *        into the current buffer any more
 *
 * This function will allocate a new buffer of twice the old buffer size. If
 * the buffer has already the maximum size kMaxBufferSize, eof is returned
 * to indicate that the buffer cannot take any more input before a flush.
 */
template <class Derived, typename C, class Allocator>
typename OutputStreamBufferBase<Derived, C, Allocator>::int_type
OutputStreamBufferBase<Derived, C, Allocator>::overflow(int_type c) {
    if (this->pptr() >= this->epptr()) {
        if (mStorageSize >= kMaxBufferSize)
            return traits_type::eof();

        uint32_t newStorageSize = mStorageSize * 2;
        C* newStorage = mAllocator.allocate(newStorageSize + 1);
        std::copy(mStorage, mStorage + mStorageSize, newStorage);
        mAllocator.deallocate(mStorage, mStorageSize + 1);
        mStorage = newStorage;

        madlib_assert(
            this->pptr() == this->epptr() &&
            this->pptr() - this->pbase() == static_cast<int64_t>(mStorageSize),
            std::logic_error("Internal error: Logging buffer has become "
                "inconsistent"));

        this->setp(mStorage, mStorage + newStorageSize);
        this->pbump(mStorageSize);
        mStorageSize = newStorageSize;
    } else if (c == traits_type::eof())
       return traits_type::eof();

    *this->pptr() = static_cast<C>(c);
    this->pbump(1);
    return traits_type::not_eof(c);
}

/**
 * @brief Flush and reset buffer.
 */
template <class Derived, typename C, class Allocator>
int
OutputStreamBufferBase<Derived, C, Allocator>::sync() {
    std::ptrdiff_t length = this->pptr() - this->pbase();

    mStorage[length] = '\0';
    output(mStorage, length);

    this->setp(mStorage, mStorage + mStorageSize);
    return 0;
}

} // namespace dbal

} // namespace madlib

#endif // defined(MADLIB_OUTPUTSTREAMBUFFERBASE_IMPL_HPP)
