qtcontactsmobility/src/versit/qversitwriter.cpp
changeset 25 76a2435edfd4
parent 24 0ba2181d7c28
child 27 de1630741fbe
equal deleted inserted replaced
24:0ba2181d7c28 25:76a2435edfd4
    38 ** $QT_END_LICENSE$
    38 ** $QT_END_LICENSE$
    39 **
    39 **
    40 ****************************************************************************/
    40 ****************************************************************************/
    41 
    41 
    42 #include "qversitwriter.h"
    42 #include "qversitwriter.h"
    43 #include "qvcard21writer_p.h"
    43 #include "qversitwriter_p.h"
    44 #include "qvcard30writer_p.h"
       
    45 #include "versitutils_p.h"
    44 #include "versitutils_p.h"
    46 #include "qmobilityglobal.h"
    45 #include "qmobilityglobal.h"
    47 
    46 
    48 #include <QStringList>
    47 #include <QStringList>
    49 
    48 #include <QTextCodec>
    50 QTM_BEGIN_NAMESPACE
    49 
       
    50 QTM_USE_NAMESPACE
    51 
    51 
    52 /*!
    52 /*!
    53   \class QVersitWriter
    53   \class QVersitWriter
    54  
    54   \preliminary 
    55   \brief The QVersitWriter class provides an interface
    55   \brief The QVersitWriter class writes Versit documents such as vCards to a device.
    56   for writing a versit document such as a vCard to a text stream.
       
    57 
       
    58   \ingroup versit
    56   \ingroup versit
    59  
    57  
    60   QVersitWriter converts a QVersitDocument into its textual representation.
    58   QVersitWriter converts a QVersitDocument into its textual representation.
    61   QVersitWriter supports writing to an abstract I/O device
    59   QVersitWriter supports writing to an abstract I/O device
    62   which can be for example a file or a memory buffer.
    60   which can be for example a file or a memory buffer.
    63   The writing can be done synchronously or asynchronously.
    61   The writing can be done asynchronously and the waitForFinished()
    64  
    62   function can be used to implement a blocking write.
    65   \code
    63 
    66   // An example of writing a simple vCard to a memory buffer:
    64   The serialization of the document is done in accordance with the type of the QVersitDocument
    67   QBuffer vCardBuffer;
    65   being written.  The value of each QVersitProperty is encoded according to the type of object:
    68   vCardBuffer.open(QBuffer::ReadWrite);
    66   \list
    69   QVersitWriter writer;
    67   \o \l{QString}{QStrings} are serialized verbatim, unless the default codec of the writer cannot
    70   writer.setDevice(&vCardBuffer);
    68   encode the string: in this case, UTF-8 is used to encode it (and the CHARSET parameter added to
    71   QVersitDocument document;
    69   the property, as per the vCard 2.1 specification).  If the document type is vCard 2.1,
    72   QVersitProperty property;
    70   quoted-printable encoding may also be performed.
    73   property.setName("N");
    71   \o \l{QByteArray}{QByteArrays} are assumed to be binary data and are serialized as base-64 encoded
    74   property.setValue("Citizen;John;Q;;");
    72   values.
    75   document.addProperty(property);
    73   \o \l{QVersitDocument}{QVersitDocuments} are serialized as a nested document (eg. as per the
    76   writer.setVersitDocument(document);
    74   AGENT property in vCard).
    77   if (writer.writeAll()) {
    75   \endlist
    78       // Use the vCardBuffer...
    76 
    79   }
       
    80   \endcode
       
    81  
       
    82   \sa QVersitDocument, QVersitProperty
    77   \sa QVersitDocument, QVersitProperty
    83  */
    78  */
    84 
    79 
    85 /*!
    80 
    86  * \fn QVersitWriter::writingDone()
    81 /*!
    87  * The signal is emitted by the writer when the asynchronous writing has been completed.
    82  * \enum QVersitWriter::Error
       
    83  * This enum specifies an error that occurred during the most recent operation:
       
    84  * \value NoError The most recent operation was successful
       
    85  * \value UnspecifiedError The most recent operation failed for an undocumented reason
       
    86  * \value IOError The most recent operation failed because of a problem with the device
       
    87  * \value OutOfMemoryError The most recent operation failed due to running out of memory
       
    88  * \value NotReadyError The most recent operation failed because there is an operation in progress
       
    89  */
       
    90 
       
    91 /*!
       
    92  * \enum QVersitWriter::State
       
    93  * Enumerates the various states that a reader may be in at any given time
       
    94  * \value InactiveState Write operation not yet started
       
    95  * \value ActiveState Write operation started, not yet finished
       
    96  * \value CanceledState Write operation is finished due to cancelation
       
    97  * \value FinishedState Write operation successfully completed
       
    98  */
       
    99 
       
   100 /*!
       
   101  * \fn QVersitWriter::stateChanged(QVersitWriter::State state)
       
   102  * The signal is emitted by the writer when its state has changed (eg. when it has finished
       
   103  * writing to the device).
       
   104  * \a state is the new state of the writer.
    88  */
   105  */
    89 
   106 
    90 /*! Constructs a new writer. */
   107 /*! Constructs a new writer. */
    91 QVersitWriter::QVersitWriter() : d(new QVCard21Writer)
   108 QVersitWriter::QVersitWriter() : d(new QVersitWriterPrivate)
    92 {
   109 {
    93     connect(d,SIGNAL(finished()),this,SIGNAL(writingDone()),Qt::DirectConnection);
   110     connect(d, SIGNAL(stateChanged(QVersitWriter::State)),
       
   111             this, SIGNAL(stateChanged(QVersitWriter::State)), Qt::DirectConnection);
    94 }
   112 }
    95 
   113 
    96 /*! 
   114 /*! 
    97  * Frees the memory used by the writer. 
   115  * Frees the memory used by the writer. 
    98  * Waits until a pending asynchronous writing has been completed.
   116  * Waits until a pending asynchronous writing has been completed.
   102     d->wait();
   120     d->wait();
   103     delete d;
   121     delete d;
   104 }
   122 }
   105 
   123 
   106 /*!
   124 /*!
   107  * Set the versit document to be written to \a versitDocument and
       
   108  * selects the actual writer implementation based on the versit document type.
       
   109  */
       
   110 void QVersitWriter::setVersitDocument(const QVersitDocument& versitDocument)
       
   111 {
       
   112     QVersitWriterPrivate* updatedWriter = 0;
       
   113     switch (versitDocument.versitType()) {
       
   114         case QVersitDocument::VCard21:
       
   115             updatedWriter = new QVCard21Writer;
       
   116             break;
       
   117         case QVersitDocument::VCard30:
       
   118             updatedWriter = new QVCard30Writer;
       
   119             break;
       
   120         default:
       
   121             break;
       
   122     }
       
   123     if (updatedWriter) {
       
   124         updatedWriter->mIoDevice = d->mIoDevice;
       
   125         delete d;
       
   126         d = updatedWriter;
       
   127         connect(d,SIGNAL(finished()),this,SIGNAL(writingDone()),Qt::DirectConnection);
       
   128     }
       
   129     d->mVersitDocument = versitDocument;
       
   130 }
       
   131 
       
   132 /*!
       
   133  * Returns the current versit document.
       
   134  */
       
   135 QVersitDocument QVersitWriter::versitDocument() const
       
   136 {
       
   137     return d->mVersitDocument;
       
   138 }
       
   139 
       
   140 /*!
       
   141  * Sets the device used for writing to \a device.
   125  * Sets the device used for writing to \a device.
   142  */
   126  */
   143 void QVersitWriter::setDevice(QIODevice* device)
   127 void QVersitWriter::setDevice(QIODevice* device)
   144 {
   128 {
   145     d->mIoDevice = device;
   129     d->mIoDevice = device;
   152 {
   136 {
   153     return d->mIoDevice;
   137     return d->mIoDevice;
   154 }
   138 }
   155 
   139 
   156 /*!
   140 /*!
   157  * Starts writing the output asynchronously.
   141  * Sets the default codec for the writer to use for writing the entire output.
       
   142  *
       
   143  * If \a codec is NULL, the writer uses the codec according to the specification prescribed default.
       
   144  * (for vCard 2.1, ASCII; for vCard 3.0, UTF-8).
       
   145  */
       
   146 void QVersitWriter::setDefaultCodec(QTextCodec *codec)
       
   147 {
       
   148     d->mDefaultCodec = codec;
       
   149 }
       
   150 
       
   151 /*!
       
   152  * Returns the document's codec.
       
   153  */
       
   154 QTextCodec* QVersitWriter::defaultCodec() const
       
   155 {
       
   156     return d->mDefaultCodec;
       
   157 }
       
   158 
       
   159 /*!
       
   160  * Starts writing \a input to device() asynchronously.
   158  * Returns false if the output device has not been set or opened or
   161  * Returns false if the output device has not been set or opened or
   159  * if there is another asynchronous write operation already pending.
   162  * if there is another asynchronous write operation already pending.
   160  * Signal \l writingDone() is emitted when the writing has finished.
   163  * Signal \l stateChanged() is emitted with parameter FinishedState
   161  */
   164  * when the writing has finished.
       
   165  */
       
   166 bool QVersitWriter::startWriting(const QList<QVersitDocument>& input)
       
   167 {
       
   168     d->mInput = input;
       
   169     if (d->state() == ActiveState || d->isRunning()) {
       
   170         d->setError(QVersitWriter::NotReadyError);
       
   171         return false;
       
   172     } else if (!d->mIoDevice || !d->mIoDevice->isWritable()) {
       
   173         d->setError(QVersitWriter::IOError);
       
   174         return false;
       
   175     } else {
       
   176         d->setState(ActiveState);
       
   177         d->setError(NoError);
       
   178         d->start();
       
   179         return true;
       
   180     }
       
   181 }
       
   182 
       
   183 /*!
       
   184  * Attempts to asynchronously cancel the write request.
       
   185  */
       
   186 void QVersitWriter::cancel()
       
   187 {
       
   188     d->setCanceling(true);
       
   189 }
       
   190 
       
   191 /*!
       
   192  * If the state is ActiveState, blocks until the writer has finished writing or \a msec milliseconds
       
   193  * has elapsed, returning true if it successfully finishes or is cancelled by the user.
       
   194  * If the state is FinishedState, returns true immediately.
       
   195  * Otherwise, returns false immediately.
       
   196  */
       
   197 bool QVersitWriter::waitForFinished(int msec)
       
   198 {
       
   199     State state = d->state();
       
   200     if (state == ActiveState) {
       
   201         return d->wait(msec);
       
   202     } else if (state == FinishedState) {
       
   203         return true;
       
   204     } else {
       
   205         return false;
       
   206     }
       
   207 }
       
   208 
       
   209 /*!
       
   210  * Returns the state of the writer.
       
   211  */
       
   212 QVersitWriter::State QVersitWriter::state() const
       
   213 {
       
   214     return d->state();
       
   215 }
       
   216 
       
   217 /*!
       
   218  * Returns the error encountered by the last operation.
       
   219  */
       
   220 QVersitWriter::Error QVersitWriter::error() const
       
   221 {
       
   222     return d->error();
       
   223 }
       
   224 
       
   225 
       
   226 /*! \internal */
       
   227 void QVersitWriter::setVersitDocument(const QVersitDocument& versitDocument)
       
   228 {
       
   229     QList<QVersitDocument> documents;
       
   230     documents.append(versitDocument);
       
   231     d->mInput = documents;
       
   232 }
       
   233 
       
   234 /*! \internal */
       
   235 QVersitDocument QVersitWriter::versitDocument() const
       
   236 {
       
   237     return QVersitDocument();
       
   238 }
       
   239 
       
   240 /*! \internal */
   162 bool QVersitWriter::startWriting()
   241 bool QVersitWriter::startWriting()
   163 {
   242 {
   164     bool started = false;
   243     return startWriting(d->mInput);
   165     if (d->isReady() && !d->isRunning()) {
   244 }
   166         d->start();
   245 
   167         started = true;
   246 /*! \internal */
   168     }
       
   169 
       
   170     return started;
       
   171 }
       
   172 
       
   173 /*!
       
   174  * Writes the output synchronously.
       
   175  * Returns false if the output device has not been set or opened or
       
   176  * if there is an asynchronous write operation pending.
       
   177  * Using this function may block the user thread for an undefined period.
       
   178  * In most cases asynchronous \l startWriting() should be used instead.
       
   179  */
       
   180 bool QVersitWriter::writeAll()
   247 bool QVersitWriter::writeAll()
   181 {
   248 {
   182     bool ok = false;
   249     startWriting(d->mInput);
   183     if (!d->isRunning())
   250     return waitForFinished();
   184         ok = d->write();
       
   185     return ok;
       
   186 }
   251 }
   187 
   252 
   188 #include "moc_qversitwriter.cpp"
   253 #include "moc_qversitwriter.cpp"
   189 
       
   190 QTM_END_NAMESPACE