21 #include "vcardparser.h"
24 #include <QtCore/QTextCodec>
41 m_values.
insert(value,
string);
53 static void addEscapes(
QByteArray &str,
bool excludeEscapteComma )
55 str.
replace(
'\\', (
char *)
"\\\\" );
56 if ( !excludeEscapteComma ) {
57 str.
replace(
',', (
char *)
"\\," );
59 str.
replace(
'\r', (
char *)
"\\r" );
60 str.
replace(
'\n', (
char *)
"\\n" );
65 str.
replace( (
char *)
"\\n",
"\n" );
66 str.
replace( (
char *)
"\\N",
"\n" );
67 str.
replace( (
char *)
"\\r",
"\r" );
68 str.
replace( (
char *)
"\\,",
"," );
69 str.
replace( (
char *)
"\\\\",
"\\" );
72 VCardParser::VCardParser()
77 VCardParser::~VCardParser()
95 for ( ; it != linesEnd; ++it ) {
97 if ( ( *it ).endsWith(
'\r' ) ) {
101 if ( ( *it ).startsWith(
' ' ) ||
102 ( *it ).startsWith(
'\t' ) ) {
103 currentLine.
append( ( *it ).mid( 1 ) );
106 if ( ( *it ).trimmed().isEmpty() ) {
109 if ( inVCard && !currentLine.
isEmpty() ) {
110 int colon = currentLine.
indexOf(
':' );
112 currentLine = ( *it );
123 int groupPos = params[ 0 ].
indexOf(
'.' );
124 if ( groupPos != -1 ) {
125 vCardLine.setGroup( cache.fromLatin1( params[ 0 ].left( groupPos ) ) );
126 vCardLine.setIdentifier( cache.fromLatin1( params[ 0 ].
mid( groupPos + 1 ) ) );
128 vCardLine.setIdentifier( cache.fromLatin1( params[ 0 ] ) );
131 if ( params.
count() > 1 ) {
133 for ( ++paramIt; paramIt != params.
constEnd(); ++paramIt ) {
135 if ( pair.
count() == 1 ) {
137 if ( pair[ 0 ].toLower() ==
"quoted-printable" ) {
138 pair[ 0 ] =
"encoding";
139 pair.
append(
"quoted-printable" );
140 }
else if ( pair[ 0 ].toLower() ==
"base64" ) {
141 pair[ 0 ] =
"encoding";
147 if ( pair[ 1 ].indexOf(
',' ) != -1 ) {
151 for ( argIt = args.
constBegin(); argIt != argEnd; ++argIt ) {
152 vCardLine.addParameter( cache.fromLatin1( pair[ 0 ].toLower() ),
153 cache.fromLatin1( *argIt ) );
156 vCardLine.addParameter( cache.fromLatin1( pair[ 0 ].toLower() ),
157 cache.fromLatin1( pair[ 1 ] ) );
162 removeEscapes( value );
165 bool wasBase64Encoded =
false;
167 if ( vCardLine.parameterList().contains(
QLatin1String(
"encoding" ) ) ) {
173 wasBase64Encoded =
true;
175 else if ( encoding ==
QLatin1String(
"quoted-printable" ) ) {
177 while ( value.
endsWith(
'=' ) && it != linesEnd ) {
182 if ( (*it).endsWith(
'\r') ) {
186 KCodecs::quotedPrintableDecode( value, output );
190 qDebug(
"Unknown vcard encoding type!" );
196 if ( vCardLine.parameterList().contains(
QLatin1String(
"charset" ) ) ) {
199 vCardLine.parameter(
QLatin1String(
"charset" ) ).toLatin1() );
201 vCardLine.setValue( codec->
toUnicode( output ) );
205 }
else if ( wasBase64Encoded ) {
206 vCardLine.setValue( output );
211 currentVCard.addLine( vCardLine );
215 if ( ( *it ).toLower().startsWith(
"begin:vcard" ) ) {
218 currentVCard.clear();
222 if ( ( *it ).toLower().startsWith(
"end:vcard" ) ) {
224 vCardList.
append( currentVCard );
226 currentVCard.clear();
230 currentLine = ( *it );
259 for ( cardIt = list.
begin(); cardIt != listEnd; ++cardIt ) {
260 text.
append(
"BEGIN:VCARD\r\n" );
262 idents = ( *cardIt ).identifiers();
270 lines = ( *cardIt ).lines( ( *identIt ) );
276 if ( ( *lineIt ).hasGroup() ) {
277 textLine = ( *lineIt ).group().toLatin1() +
'.' + ( *lineIt ).identifier().toLatin1();
279 textLine = ( *lineIt ).identifier().toLatin1();
282 params = ( *lineIt ).parameterList();
285 for ( paramIt = params.
begin(); paramIt != params.
end(); ++paramIt ) {
291 values = ( *lineIt ).parameters( *paramIt );
293 textLine.
append(
';' + ( *paramIt ).toLatin1().toUpper() );
294 if ( !( *valueIt ).isEmpty() ) {
295 textLine.
append(
'=' + ( *valueIt ).toLatin1() );
301 bool checkMultibyte =
false;
304 if ( ( *lineIt ).parameterList().contains(
QLatin1String(
"charset" ) ) ) {
306 const QString value = ( *lineIt ).value().toString();
308 ( *lineIt ).parameter(
QLatin1String(
"charset" ) ).toLatin1() );
312 checkMultibyte =
true;
315 }
else if ( ( *lineIt ).value().type() == QVariant::ByteArray ) {
316 input = ( *lineIt ).value().toByteArray();
318 checkMultibyte =
true;
319 input = ( *lineIt ).value().toString().toUtf8();
325 checkMultibyte =
false;
327 }
else if ( encodingType ==
QLatin1String(
"quoted-printable" ) ) {
328 checkMultibyte =
false;
329 KCodecs::quotedPrintableEncode( input, output,
false );
334 addEscapes( output, (( *lineIt ).identifier() ==
QLatin1String(
"CATEGORIES" )|| ( *lineIt ).identifier() ==
QLatin1String(
"GEO" )) );
337 textLine.
append(
':' + output );
339 if ( textLine.
length() > FOLD_WIDTH ) {
340 if ( checkMultibyte ) {
344 for (
int i = 0; i < textLine.
length(); ++i ) {
345 if ( (textLine[i] & 0xC0) == 0xC0 ) {
346 int sequenceLength = 2;
347 if ( (textLine[i] & 0xE0) == 0xE0 ) {
349 }
else if ( (textLine[i] & 0xF0) == 0xF0 ) {
352 if ( (lineLength + sequenceLength) > FOLD_WIDTH ) {
354 text +=
"\r\n " + textLine.
mid(i, sequenceLength);
355 lineLength = 1 + sequenceLength;
357 text += textLine.
mid(i, sequenceLength);
358 lineLength += sequenceLength;
360 i += sequenceLength - 1;
365 if ( (lineLength == FOLD_WIDTH) && (i < (textLine.
length() - 1)) ) {
372 for (
int i = 0; i <= ( textLine.
length() / FOLD_WIDTH ); ++i ) {
374 ( i == 0 ?
"" :
" " ) + textLine.
mid( i * FOLD_WIDTH, FOLD_WIDTH ) +
"\r\n" );
378 text.
append( textLine +
"\r\n" );
385 text.
append(
"END:VCARD\r\n" );
QByteArray fromUnicode(const QString &str) const
QList< QByteArray > split(char sep) const
QByteArray trimmed() const
bool contains(const QString &str, Qt::CaseSensitivity cs) const
const_iterator constFind(const Key &key) const
int indexOf(const T &value, int from) const
int indexOf(char ch, int from) const
int count(const T &value) const
void append(const T &value)
QString fromUtf8(const char *str, int size)
QString & insert(int position, QChar ch)
const_iterator constEnd() const
QByteArray & replace(int pos, int len, const char *after)
QByteArray mid(int pos, int len) const
QByteArray & append(char ch)
const T value(const Key &key) const
QByteArray left(int len) const
QByteArray fromBase64(const QByteArray &base64)
QTextCodec * codecForName(const QByteArray &name)
QList< T > mid(int pos, int length) const
QString fromLatin1(const char *str, int size)
int indexOf(const QRegExp &rx, int from) const
void prepend(const T &value)
QByteArray toBase64() const
const_iterator constEnd() const
const_iterator constBegin() const
bool endsWith(const QByteArray &ba) const
QString toUnicode(const QByteArray &a) const
QByteArray toUtf8() const