summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Wu Won <kevin.wuwon@nokia.com>2011-01-14 16:57:08 +1000
committerKevin Wu Won <kevin.wuwon@nokia.com>2011-01-14 17:27:36 +1000
commit0d2aad9c04a7f2327ac8ae83cb7565a532a3811a (patch)
treed6c98c627dfe185f2c61a60b7aa803cd0682ab38
parent4d59e71d6d385b7e18bdf2ca0d8f9a1a3118f7d3 (diff)
QVCard21Writer: Use Quoted-Printable soft-line breaks for wrapping
This is necessary because Symbian devices don't support vCard-style folding on Quoted-Printable properties. Task-number: MOBILITY-2353 Reviewed-by: Michael Goddard Change-Id: I59fdd6a448c64e4b94b2840596120f0869a435f1
-rw-r--r--src/versit/qvcard21writer.cpp8
-rw-r--r--src/versit/qversitdocumentwriter_p.cpp34
-rw-r--r--src/versit/qversitdocumentwriter_p.h1
-rw-r--r--tests/auto/qvcard21writer/qvcard21writer.pro1
-rw-r--r--tests/auto/qvcard21writer/tst_qvcard21writer.cpp31
5 files changed, 68 insertions, 7 deletions
diff --git a/src/versit/qvcard21writer.cpp b/src/versit/qvcard21writer.cpp
index b9acf7de74..9055cbfb2a 100644
--- a/src/versit/qvcard21writer.cpp
+++ b/src/versit/qvcard21writer.cpp
@@ -129,7 +129,13 @@ void QVCard21Writer::encodeVersitProperty(const QVersitProperty& property)
QVersitDocument embeddedDocument = variant.value<QVersitDocument>();
encodeVersitDocument(embeddedDocument);
} else if (variant.type() == QVariant::String || variant.type() == QVariant::StringList) {
- writeString(renderedValue);
+ // Some devices don't support vCard-style line folding if the property is
+ // quoted-printable-encoded. Therefore, we use QP soft linebreaks if the property is being
+ // QP-encoded, and normal vCard folding otherwise.
+ if (parameters.contains("ENCODING", QLatin1String("QUOTED-PRINTABLE")))
+ writeStringQp(renderedValue);
+ else
+ writeString(renderedValue);
} else if (variant.type() == QVariant::ByteArray) {
// One extra folding before the value and
// one extra line break after the value are needed in vCard 2.1
diff --git a/src/versit/qversitdocumentwriter_p.cpp b/src/versit/qversitdocumentwriter_p.cpp
index f81cfdb006..e8f5093aea 100644
--- a/src/versit/qversitdocumentwriter_p.cpp
+++ b/src/versit/qversitdocumentwriter_p.cpp
@@ -237,6 +237,40 @@ void QVersitDocumentWriter::writeString(const QString &value)
}
/*!
+ Writes \a value to the device.
+
+ This function tracks how many characters have been written to the line and wraps the line
+ according to RFC2045 (a Quoted-Printable soft line break is an EQUALS-CR-LF sequence)
+ */
+void QVersitDocumentWriter::writeStringQp(const QString &value)
+{
+ int spaceRemaining = MAX_LINE_LENGTH - mCurrentLineLength - 1;
+ // minus 1 for the equals required at the end
+ int charsWritten = 0;
+ QString softBreak(QLatin1String("=\r\n"));
+ while (spaceRemaining < value.length() - charsWritten) {
+ // Write the first "spaceRemaining" characters
+ if (value[charsWritten + spaceRemaining - 2] == QLatin1Char('=')) {
+ spaceRemaining -= 2;
+ } else if (value[charsWritten + spaceRemaining - 1] == QLatin1Char('=')) {
+ spaceRemaining -= 1;
+ }
+ QStringRef line(&value, charsWritten, spaceRemaining);
+
+ charsWritten += spaceRemaining;
+ if (mDevice->write(mEncoder->fromUnicode(line.constData(), line.length())) < 0
+ || mDevice->write(mEncoder->fromUnicode(softBreak)) < 0)
+ mSuccessful = false;
+ spaceRemaining = MAX_LINE_LENGTH - 1; // minus 1 for the equals required at the end
+ mCurrentLineLength = 0;
+ }
+
+ if (mDevice->write(mEncoder->fromUnicode(value.mid(charsWritten))) < 0)
+ mSuccessful = false;
+ mCurrentLineLength += value.length() - charsWritten;
+}
+
+/*!
Writes a CRLF to the device. By using this function, rather than writeString("\\r\\n"), you will
allow the writer to know where a line starts, for folding purposes.
*/
diff --git a/src/versit/qversitdocumentwriter_p.h b/src/versit/qversitdocumentwriter_p.h
index f3c86dd18d..9e1f119d04 100644
--- a/src/versit/qversitdocumentwriter_p.h
+++ b/src/versit/qversitdocumentwriter_p.h
@@ -82,6 +82,7 @@ public:
void writeBytes(const QByteArray& value);
void writeString(const QString& value);
+ void writeStringQp(const QString& value);
void writeCrlf();
protected:
diff --git a/tests/auto/qvcard21writer/qvcard21writer.pro b/tests/auto/qvcard21writer/qvcard21writer.pro
index dc44c81ef4..67974cf696 100644
--- a/tests/auto/qvcard21writer/qvcard21writer.pro
+++ b/tests/auto/qvcard21writer/qvcard21writer.pro
@@ -4,7 +4,6 @@ TARGET=tst_qvcard21writer
CONFIG+=testcase
include(../../../common.pri)
-DEFINES += QT_ASCII_CAST_WARNINGS
DEPENDPATH += .
INCLUDEPATH += \
diff --git a/tests/auto/qvcard21writer/tst_qvcard21writer.cpp b/tests/auto/qvcard21writer/tst_qvcard21writer.cpp
index df6a5fc431..35701f8af8 100644
--- a/tests/auto/qvcard21writer/tst_qvcard21writer.cpp
+++ b/tests/auto/qvcard21writer/tst_qvcard21writer.cpp
@@ -86,7 +86,11 @@ void tst_QVCard21Writer::testEncodeVersitProperty()
buffer.open(QIODevice::WriteOnly);
mWriter->encodeVersitProperty(property);
- QCOMPARE(encodedProperty, expectedResult);
+ if (encodedProperty != expectedResult) {
+ qDebug() << "Encoded: " << encodedProperty;
+ qDebug() << "Expected: " << expectedResult;
+ QVERIFY(false);
+ }
}
void tst_QVCard21Writer::testEncodeVersitProperty_data()
@@ -176,13 +180,30 @@ END:VCARD\r\n\
// Characters other than ASCII:
// Note: KATAKANA_NOKIA is defined as: QString::fromUtf8("\xe3\x83\x8e\xe3\x82\xad\xe3\x82\xa2")
- // The expected behaviour is to convert to UTF8, then encode with quoted-printable
- expectedResult = "ORG;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:=E3=83=8E=E3=82=AD=E3=82=A2\r\n";
+ // The expected behaviour is to convert to UTF8, then encode with quoted-printable.
+ // Because the result overflows one line, it should be split onto two lines using a
+ // quoted-printable soft line break (EQUALS-CR-LF). (Note: Versit soft line breaks
+ // (CR-LF-SPACE) are not supported by the native Symbian vCard importers).
+ expectedResult = "ORG;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:=E3=83=8E=E3=82=AD=E3=82=A2=E3=\r\n"
+ "=83=8E=E3=82=AD=E3=82=A2\r\n";
+ property = QVersitProperty();
+ property.setName(QLatin1String("ORG"));
+ property.setValue(KATAKANA_NOKIA + KATAKANA_NOKIA);
+ QTest::newRow("non-ASCII 1") << property << expectedResult << codec;
+ expectedResult = "ORG;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:a=E3=83=8E=E3=82=AD=E3=82=A2=E3=\r\n"
+ "=83=8E=E3=82=AD=E3=82=A2\r\n";
property = QVersitProperty();
property.setName(QLatin1String("ORG"));
- property.setValue(KATAKANA_NOKIA);
- QTest::newRow("non-ASCII") << property << expectedResult << codec;
+ property.setValue("a" + KATAKANA_NOKIA + KATAKANA_NOKIA);
+ QTest::newRow("non-ASCII 2") << property << expectedResult << codec;
+
+ expectedResult = "ORG;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:aa=E3=83=8E=E3=82=AD=E3=82=A2=\r\n"
+ "=E3=83=8E=E3=82=AD=E3=82=A2\r\n";
+ property = QVersitProperty();
+ property.setName(QLatin1String("ORG"));
+ property.setValue("aa" + KATAKANA_NOKIA + KATAKANA_NOKIA);
+ QTest::newRow("non-ASCII 3") << property << expectedResult << codec;
// In Shift-JIS codec.
QTextCodec* jisCodec = QTextCodec::codecForName("Shift-JIS");