/**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtVersit module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or (at your option) the GNU General ** Public license version 3 or any later version approved by the KDE Free ** Qt Foundation. The licenses are as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-2.0.html and ** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qversitreader.h" #include "qversitreader_p.h" #include #include QT_BEGIN_NAMESPACE_VERSIT /*! \class QVersitReader \brief The QVersitReader class provides an interface for reading versit documents such as vCards from a Stream. \ingroup versit \inmodule QtVersit QVersitReader concatenation of Versit documents such as vCards from a text stream and returns a list of QVersitDocument instances. QVersitReader supports reading from an abstract I/O device which can be, for example, a file or a memory buffer. The reading can be done asynchronously, and the waitForFinished() function can be used to make a blocking read. \sa QVersitDocument */ /*! * \enum QVersitReader::Error * This enum specifies an error that occurred during the most recent operation: * \value NoError The most recent operation was successful * \value UnspecifiedError The most recent operation failed for an undocumented reason * \value IOError The most recent operation failed because of a problem with the device * \value OutOfMemoryError The most recent operation failed due to running out of memory * \value NotReadyError The most recent operation failed because there is an operation in progress * \value ParseError The most recent operation failed because the input was malformed */ /*! * \enum QVersitReader::State * Enumerates the various states that a reader may be in at any given time * \value InactiveState Read operation not yet started * \value ActiveState Read operation started, not yet finished * \value CanceledState Read operation is finished due to cancellation * \value FinishedState Read operation successfully completed */ /*! * \fn QVersitReader::stateChanged(QVersitReader::State state) * The signal is emitted by the reader when its state has changed (eg. when it has finished * reading from the device). * \a state is the new state of the reader. */ /*! * \fn QVersitReader::resultsAvailable() * The signal is emitted by the reader as it reads from the device when it has made more Versit * documents available. */ /*! Constructs a new reader. */ QVersitReader::QVersitReader() : d(new QVersitReaderPrivate) { d->init(this); } /*! Constructs a new reader that reads from \a inputDevice. */ QVersitReader::QVersitReader(QIODevice *inputDevice) : d(new QVersitReaderPrivate) { d->init(this); d->mIoDevice = inputDevice; } /*! Constructs a new reader that reads from \a inputData. */ QVersitReader::QVersitReader(const QByteArray &inputData) : d(new QVersitReaderPrivate) { d->init(this); d->mInputBytes.reset(new QBuffer); d->mInputBytes->setData(inputData); d->mInputBytes->open(QIODevice::ReadOnly); d->mIoDevice = d->mInputBytes.data(); } /*! * Frees the memory used by the reader. * Waits until a pending asynchronous reading has been completed. */ QVersitReader::~QVersitReader() { d->wait(); delete d; } /*! * Sets the device used for reading the input to be the given \a device. * Does not take ownership of the device. This overrides any byte array input source set with * setData(). * * The caller must ensure that \a device remains valid for the lifetime of * this QVersitReader object. */ void QVersitReader::setDevice(QIODevice* device) { d->mInputBytes.reset(0); d->mIoDevice = device; } /*! * Returns the device used for reading input, or 0 if no device has been set (or if the input source * was set with setData(). */ QIODevice* QVersitReader::device() const { if (d->mInputBytes.isNull()) return d->mIoDevice; else return 0; } /*! * Sets the data to read from to the byte array input source, \a inputData. * This overrides any device set with setDevice(). */ void QVersitReader::setData(const QByteArray &inputData) { if (d->mInputBytes.isNull()) { d->mInputBytes.reset(new QBuffer); } else if (d->mInputBytes->isOpen()) { d->mInputBytes->close(); } d->mInputBytes->setData(inputData); d->mInputBytes->open(QIODevice::ReadOnly); d->mIoDevice = d->mInputBytes.data(); } /*! * Sets \a codec as the codec for the reader to use when parsing the input stream to. * This codec is not used for values where the CHARSET Versit parameter occurs. * If the codec is null, this denotes that the reader will try to detect the codec * from the input. The codec autodetection algorithm can detect UTF-8, UTF-16 or * UTF-32. If the input is in some 8-bit codec, it will fall back to using the system * locale's codec. */ void QVersitReader::setDefaultCodec(QTextCodec *codec) { d->mDefaultCodec = codec; } /*! * Returns the codec the reader uses when parsing the input stream. If the codec is * null, this denotes that the reader will try to detect the codec from the input. */ QTextCodec* QVersitReader::defaultCodec() const { return d->mDefaultCodec; } /*! * Returns the state of the reader. */ QVersitReader::State QVersitReader::state() const { return d->state(); } /*! * Returns the error encountered by the last operation. */ QVersitReader::Error QVersitReader::error() const { return d->error(); } /*! * Starts reading the input asynchronously. * Returns false if the input device has not been set or opened or * if there is another asynchronous read operation already pending. * Signal \l stateChanged() is emitted with parameter FinishedState * when the reading has finished. * * The device must be already open. The client is responsible for * closing it when finished. */ bool QVersitReader::startReading() { if (d->state() == ActiveState || d->isRunning()) { d->setError(QVersitReader::NotReadyError); return false; } else if (!d->mIoDevice || !d->mIoDevice->isReadable()) { d->setError(QVersitReader::IOError); return false; } else { d->setState(ActiveState); d->setError(NoError); d->setCanceling(false); d->start(); return true; } } /*! * Attempts to asynchronously cancel the read request. */ void QVersitReader::cancel() { d->setCanceling(true); } /*! * If the state is ActiveState, blocks until the reader has finished reading or \a msec milliseconds * has elapsed, returning true if it successfully finishes or is cancelled by the user. * If \a msec is negative or zero, the function blocks until the writer has finished, regardless of * how long it takes. * If the state is FinishedState, returns true immediately. * Otherwise, returns false immediately. */ bool QVersitReader::waitForFinished(int msec) { State state = d->state(); if (state != InactiveState) { if (msec <= 0) return d->wait(ULONG_MAX); else return d->wait(msec); } else { return false; } } /*! * Returns the reading result. Even if there was an error or reading has not completed, a partial * list of results may be returned. */ QList QVersitReader::results() const { QMutexLocker locker(&d->mMutex); return d->mVersitDocuments; } QT_END_NAMESPACE_VERSIT #include "moc_qversitreader.cpp"