/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qbuffer.h"
#include "private/qiodevice_p.h"

QT_BEGIN_NAMESPACE

/** QBufferPrivate **/
class QBufferPrivate : public QIODevicePrivate
{
    Q_DECLARE_PUBLIC(QBuffer)

public:
    QBufferPrivate()
    : buf(0)
#ifndef QT_NO_QOBJECT
        , writtenSinceLastEmit(0), signalConnectionCount(0), signalsEmitted(false)
#endif
    { }
    ~QBufferPrivate() { }

    QByteArray *buf;
    QByteArray defaultBuf;
    int ioIndex;

    virtual qint64 peek(char *data, qint64 maxSize);
    virtual QByteArray peek(qint64 maxSize);

#ifndef QT_NO_QOBJECT
    // private slots
    void _q_emitSignals();

    qint64 writtenSinceLastEmit;
    int signalConnectionCount;
    bool signalsEmitted;
#endif
};

#ifndef QT_NO_QOBJECT
void QBufferPrivate::_q_emitSignals()
{
    Q_Q(QBuffer);
    emit q->bytesWritten(writtenSinceLastEmit);
    writtenSinceLastEmit = 0;
    emit q->readyRead();
    signalsEmitted = false;
}
#endif

qint64 QBufferPrivate::peek(char *data, qint64 maxSize)
{
    qint64 readBytes = qMin(maxSize, static_cast<qint64>(buf->size()) - pos);
    memcpy(data, buf->constData() + pos, readBytes);
    return readBytes;
}

QByteArray QBufferPrivate::peek(qint64 maxSize)
{
    qint64 readBytes = qMin(maxSize, static_cast<qint64>(buf->size()) - pos);
    if (pos == 0 && maxSize >= buf->size())
        return *buf;
    return QByteArray(buf->constData() + pos, readBytes);
}

/*!
    \class QBuffer
    \reentrant
    \brief The QBuffer class provides a QIODevice interface for a QByteArray.

    \ingroup io

    QBuffer allows you to access a QByteArray using the QIODevice
    interface. The QByteArray is treated just as a standard random-accessed
    file. Example:

    \snippet doc/src/snippets/buffer/buffer.cpp 0

    By default, an internal QByteArray buffer is created for you when
    you create a QBuffer. You can access this buffer directly by
    calling buffer(). You can also use QBuffer with an existing
    QByteArray by calling setBuffer(), or by passing your array to
    QBuffer's constructor.

    Call open() to open the buffer. Then call write() or
    putChar() to write to the buffer, and read(), readLine(),
    readAll(), or getChar() to read from it. size() returns the
    current size of the buffer, and you can seek to arbitrary
    positions in the buffer by calling seek(). When you are done with
    accessing the buffer, call close().

    The following code snippet shows how to write data to a
    QByteArray using QDataStream and QBuffer:

    \snippet doc/src/snippets/buffer/buffer.cpp 1

    Effectively, we convert the application's QPalette into a byte
    array. Here's how to read the data from the QByteArray:

    \snippet doc/src/snippets/buffer/buffer.cpp 2

    QTextStream and QDataStream also provide convenience constructors
    that take a QByteArray and that create a QBuffer behind the
    scenes.

    QBuffer emits readyRead() when new data has arrived in the
    buffer. By connecting to this signal, you can use QBuffer to
    store temporary data before processing it. For example, you can
    pass the buffer to QFtp when downloading a file from an FTP
    server. Whenever a new payload of data has been downloaded,
    readyRead() is emitted, and you can process the data that just
    arrived. QBuffer also emits bytesWritten() every time new data
    has been written to the buffer.

    \sa QFile, QDataStream, QTextStream, QByteArray
*/

#ifdef QT_NO_QOBJECT
QBuffer::QBuffer()
    : QIODevice(*new QBufferPrivate)
{
    Q_D(QBuffer);
    d->buf = &d->defaultBuf;
    d->ioIndex = 0;
}
QBuffer::QBuffer(QByteArray *buf)
    : QIODevice(*new QBufferPrivate)
{
    Q_D(QBuffer);
    d->buf = buf ? buf : &d->defaultBuf;
    d->ioIndex = 0;
    d->defaultBuf.clear();
}
#else
/*!
    Constructs an empty buffer with the given \a parent. You can call
    setData() to fill the buffer with data, or you can open it in
    write mode and use write().

    \sa open()
*/
QBuffer::QBuffer(QObject *parent)
    : QIODevice(*new QBufferPrivate, parent)
{
    Q_D(QBuffer);
    d->buf = &d->defaultBuf;
    d->ioIndex = 0;
}

/*!
    Constructs a QBuffer that uses the QByteArray pointed to by \a
    byteArray as its internal buffer, and with the given \a parent.
    The caller is responsible for ensuring that \a byteArray remains
    valid until the QBuffer is destroyed, or until setBuffer() is
    called to change the buffer. QBuffer doesn't take ownership of
    the QByteArray.

    If you open the buffer in write-only mode or read-write mode and
    write something into the QBuffer, \a byteArray will be modified.

    Example:

    \snippet doc/src/snippets/buffer/buffer.cpp 3

    \sa open(), setBuffer(), setData()
*/
QBuffer::QBuffer(QByteArray *byteArray, QObject *parent)
    : QIODevice(*new QBufferPrivate, parent)
{
    Q_D(QBuffer);
    d->buf = byteArray ? byteArray : &d->defaultBuf;
    d->defaultBuf.clear();
    d->ioIndex = 0;
}
#endif

/*!
    Destroys the buffer.
*/

QBuffer::~QBuffer()
{
}

/*!
    Makes QBuffer uses the QByteArray pointed to by \a
    byteArray as its internal buffer. The caller is responsible for
    ensuring that \a byteArray remains valid until the QBuffer is
    destroyed, or until setBuffer() is called to change the buffer.
    QBuffer doesn't take ownership of the QByteArray.

    Does nothing if isOpen() is true.

    If you open the buffer in write-only mode or read-write mode and
    write something into the QBuffer, \a byteArray will be modified.

    Example:

    \snippet doc/src/snippets/buffer/buffer.cpp 4

    If \a byteArray is 0, the buffer creates its own internal
    QByteArray to work on. This byte array is initially empty.

    \sa buffer(), setData(), open()
*/

void QBuffer::setBuffer(QByteArray *byteArray)
{
    Q_D(QBuffer);
    if (isOpen()) {
        qWarning("QBuffer::setBuffer: Buffer is open");
        return;
    }
    if (byteArray) {
        d->buf = byteArray;
    } else {
        d->buf = &d->defaultBuf;
    }
    d->defaultBuf.clear();
    d->ioIndex = 0;
}

/*!
    Returns a reference to the QBuffer's internal buffer. You can use
    it to modify the QByteArray behind the QBuffer's back.

    \sa setBuffer(), data()
*/

QByteArray &QBuffer::buffer()
{
    Q_D(QBuffer);
    return *d->buf;
}

/*!
    \overload

    This is the same as data().
*/

const QByteArray &QBuffer::buffer() const
{
    Q_D(const QBuffer);
    return *d->buf;
}


/*!
    Returns the data contained in the buffer.

    This is the same as buffer().

    \sa setData(), setBuffer()
*/

const QByteArray &QBuffer::data() const
{
    Q_D(const QBuffer);
    return *d->buf;
}

/*!
    Sets the contents of the internal buffer to be \a data. This is
    the same as assigning \a data to buffer().

    Does nothing if isOpen() is true.

    \sa setBuffer()
*/
void QBuffer::setData(const QByteArray &data)
{
    Q_D(QBuffer);
    if (isOpen()) {
        qWarning("QBuffer::setData: Buffer is open");
        return;
    }
    *d->buf = data;
    d->ioIndex = 0;
}

/*!
    \fn void QBuffer::setData(const char *data, int size)

    \overload

    Sets the contents of the internal buffer to be the first \a size
    bytes of \a data.
*/

/*!
   \reimp
*/
bool QBuffer::open(OpenMode flags)
{
    Q_D(QBuffer);

    if ((flags & Append) == Append)
        flags |= WriteOnly;
    setOpenMode(flags);
    if (!(isReadable() || isWritable())) {
        qWarning("QFile::open: File access not specified");
        return false;
    }

    if ((flags & QIODevice::Truncate) == QIODevice::Truncate) {
        d->buf->resize(0);
    }
    if ((flags & QIODevice::Append) == QIODevice::Append) // append to end of buffer
        seek(d->buf->size());
    else
        seek(0);

    return true;
}

/*!
    \reimp
*/
void QBuffer::close()
{
    QIODevice::close();
}

/*!
    \reimp
*/
qint64 QBuffer::pos() const
{
    return QIODevice::pos();
}

/*!
    \reimp
*/
qint64 QBuffer::size() const
{
    Q_D(const QBuffer);
    return qint64(d->buf->size());
}

/*!
    \reimp
*/
bool QBuffer::seek(qint64 pos)
{
    Q_D(QBuffer);
    if (pos > d->buf->size() && isWritable()) {
        if (seek(d->buf->size())) {
            const qint64 gapSize = pos - d->buf->size();
            if (write(QByteArray(gapSize, 0)) != gapSize) {
                qWarning("QBuffer::seek: Unable to fill gap");
                return false;
            }
        } else {
            return false;
        }
    } else if (pos > d->buf->size() || pos < 0) {
        qWarning("QBuffer::seek: Invalid pos: %d", int(pos));
        return false;
    }
    d->ioIndex = int(pos);
    return QIODevice::seek(pos);
}

/*!
    \reimp
*/
bool QBuffer::atEnd() const
{
    return QIODevice::atEnd();
}

/*!
   \reimp
*/
bool QBuffer::canReadLine() const
{
    Q_D(const QBuffer);
    if (!isOpen())
        return false;

    return d->buf->indexOf('\n', int(pos())) != -1 || QIODevice::canReadLine();
}

/*!
    \reimp
*/
qint64 QBuffer::readData(char *data, qint64 len)
{
    Q_D(QBuffer);
    if ((len = qMin(len, qint64(d->buf->size()) - d->ioIndex)) <= 0)
        return qint64(0);
    memcpy(data, d->buf->constData() + d->ioIndex, len);
    d->ioIndex += int(len);
    return len;
}

/*!
    \reimp
*/
qint64 QBuffer::writeData(const char *data, qint64 len)
{
    Q_D(QBuffer);
    int extraBytes = d->ioIndex + len - d->buf->size();
    if (extraBytes > 0) { // overflow
        int newSize = d->buf->size() + extraBytes;
        d->buf->resize(newSize);
        if (d->buf->size() != newSize) { // could not resize
            qWarning("QBuffer::writeData: Memory allocation error");
            return -1;
        }
    }

    memcpy(d->buf->data() + d->ioIndex, (uchar *)data, int(len));
    d->ioIndex += int(len);

#ifndef QT_NO_QOBJECT
    d->writtenSinceLastEmit += len;
    if (d->signalConnectionCount && !d->signalsEmitted && !signalsBlocked()) {
        d->signalsEmitted = true;
        QMetaObject::invokeMethod(this, "_q_emitSignals", Qt::QueuedConnection);
    }
#endif
    return len;
}

#ifndef QT_NO_QOBJECT
/*!
    \reimp
    \internal
*/
void QBuffer::connectNotify(const char *signal)
{
    if (strcmp(signal + 1, "readyRead()") == 0 || strcmp(signal + 1, "bytesWritten(qint64)") == 0)
        d_func()->signalConnectionCount++;
}

/*!
    \reimp
    \internal
*/
void QBuffer::disconnectNotify(const char *signal)
{
    if (!signal || strcmp(signal + 1, "readyRead()") == 0 || strcmp(signal + 1, "bytesWritten(qint64)") == 0)
        d_func()->signalConnectionCount--;
}
#endif

QT_END_NAMESPACE

#ifndef QT_NO_QOBJECT
# include "moc_qbuffer.cpp"
#endif

