Index: kabc/vcardconverter.cpp =================================================================== --- kabc/vcardconverter.cpp.orig +++ kabc/vcardconverter.cpp @@ -51,6 +51,14 @@ QString VCardConverter::createVCard( con return createVCards( list, version ); } +QCString VCardConverter::createVCardRaw( const Addressee &addr, Version version ) +{ + Addressee::List list; + list.append( addr ); + + return createVCardsRaw( list, version ); +} + QString VCardConverter::createVCards( Addressee::List list, Version version ) { VCardTool tool; @@ -58,6 +66,13 @@ QString VCardConverter::createVCards( Ad return tool.createVCards( list, ( version == v3_0 ? VCard::v3_0 : VCard::v2_1 ) ); } +QCString VCardConverter::createVCardsRaw( Addressee::List list, Version version ) +{ + VCardTool tool; + + return tool.createVCardsRaw( list, ( version == v3_0 ? VCard::v3_0 : VCard::v2_1 ) ); +} + Addressee VCardConverter::parseVCard( const QString& vcard ) { Addressee::List list = parseVCards( vcard ); @@ -65,6 +80,13 @@ Addressee VCardConverter::parseVCard( co return list[ 0 ]; } +Addressee VCardConverter::parseVCardRaw( const QCString& vcard ) +{ + Addressee::List list = parseVCardsRaw( vcard ); + + return list[ 0 ]; +} + Addressee::List VCardConverter::parseVCards( const QString& vcard ) { VCardTool tool; @@ -72,6 +94,13 @@ Addressee::List VCardConverter::parseVCa return tool.parseVCards( vcard ); } +Addressee::List VCardConverter::parseVCardsRaw( const QCString& vcard ) +{ + VCardTool tool; + + return tool.parseVCardsRaw( vcard ); +} + // ---------------------------- deprecated stuff ---------------------------- // bool VCardConverter::vCardToAddressee( const QString &str, Addressee &addr, Version version ) Index: kabc/vcardconverter.h =================================================================== --- kabc/vcardconverter.h.orig +++ kabc/vcardconverter.h @@ -82,6 +82,7 @@ class KABC_EXPORT VCardConverter @param version The version of the generated vCard format */ QString createVCard( const Addressee &addr, Version version = v3_0 ); + QCString createVCardRaw( const Addressee &addr, Version version = v3_0 ); /** Creates a string in vCard format which contains the given @@ -92,6 +93,7 @@ class KABC_EXPORT VCardConverter */ // FIXME: Add error handling QString createVCards( Addressee::List list, Version version = v3_0 ); + QCString createVCardsRaw( Addressee::List list, Version version = v3_0 ); // FIXME: Add "createVCards( AddressBook * )" @@ -99,12 +101,14 @@ class KABC_EXPORT VCardConverter Parses a string in vCard format and returns the first contact. */ Addressee parseVCard( const QString& vcard ); + Addressee parseVCardRaw( const QCString& vcard ); /** Parses a string in vCard format and returns a list of contact objects. */ // FIXME: Add error handling Addressee::List parseVCards( const QString& vcard ); + Addressee::List parseVCardsRaw( const QCString& vcard ); // FIXME: Add "bool parseVCards( AddressBook *, const QString &vcard )" Index: kabc/vcardformatplugin.cpp =================================================================== --- kabc/vcardformatplugin.cpp.orig +++ kabc/vcardformatplugin.cpp @@ -38,14 +38,11 @@ VCardFormatPlugin::~VCardFormatPlugin() bool VCardFormatPlugin::load( Addressee &addressee, QFile *file ) { - QString data; - - QTextStream t( file ); - t.setEncoding( QTextStream::Latin1 ); - data = t.read(); + const QByteArray rawData = file->readAll(); + const QCString data( rawData.data(), rawData.size() ); VCardConverter converter; - Addressee::List l = converter.parseVCards( data ); + Addressee::List l = converter.parseVCardsRaw( data ); if ( ! l.first().isEmpty() ) { addressee = l.first(); @@ -57,15 +54,11 @@ bool VCardFormatPlugin::load( Addressee bool VCardFormatPlugin::loadAll( AddressBook*, Resource *resource, QFile *file ) { - QString data; - - QTextStream t( file ); - t.setEncoding( QTextStream::Latin1 ); - data = t.read(); + const QByteArray rawData = file->readAll(); + const QCString data( rawData.data(), rawData.size() ); VCardConverter converter; - - Addressee::List l = converter.parseVCards( data ); + Addressee::List l = converter.parseVCardsRaw( data ); Addressee::List::iterator itr; for ( itr = l.begin(); itr != l.end(); ++itr) { @@ -86,9 +79,8 @@ void VCardFormatPlugin::save( const Addr vcardlist.append( addressee ); - QTextStream t( file ); - t.setEncoding( QTextStream::UnicodeUTF8 ); - t << converter.createVCards( vcardlist ); + const QCString data = converter.createVCardsRaw( vcardlist ); + file->writeBlock( data, data.length() ); } void VCardFormatPlugin::saveAll( AddressBook*, Resource *resource, QFile *file ) @@ -102,9 +94,8 @@ void VCardFormatPlugin::saveAll( Address vcardlist.append( *it ); } - QTextStream t( file ); - t.setEncoding( QTextStream::UnicodeUTF8 ); - t << converter.createVCards( vcardlist ); + const QCString data = converter.createVCardsRaw( vcardlist ); + file->writeBlock( data, data.length() ); } bool VCardFormatPlugin::checkFormat( QFile *file ) const Index: kabc/vcardparser/vcardparser.cpp =================================================================== --- kabc/vcardparser/vcardparser.cpp.orig +++ kabc/vcardparser/vcardparser.cpp @@ -18,10 +18,13 @@ Boston, MA 02110-1301, USA. */ +#include <qcstring.h> #include <qregexp.h> #include <qtextcodec.h> +#include <qvaluelist.h> #include <kmdcodec.h> +#include <kdebug.h> #include "vcardparser.h" @@ -29,25 +32,60 @@ using namespace KABC; -static QString backslash( "\\\\" ); -static QString comma( "\\," ); -static QString newline( "\\n" ); -static QString cr( "\\r" ); +typedef QValueList<QCString> QCStringList; -static void addEscapes( QString &str ) +QValueList<QCString> splitCString( const QCString &str, char sep ) { - str.replace( '\\', backslash ); - str.replace( ',', comma ); - str.replace( '\r', cr ); - str.replace( '\n', newline ); + QValueList<QCString> list; + int start = 0; + int end; + while ((end = str.find(sep, start)) != -1) { + list.append(str.mid(start, end - start)); + start = end + 1; + } + list.append(str.mid(start)); + + return list; +} + +QValueList<QCString> splitCString( const QCString &str, const QRegExp &exp ) +{ + QValueList<QCString> list; + int start = 0; + int end; + while ((end = str.find(exp, start)) != -1) { + list.append(str.mid(start, end - start)); + start = end + 1; + } + list.append(str.mid(start)); + + return list; +} + +bool cStringStartsWith( const QCString &str, const QCString &pattern ) +{ + const int length = pattern.length(); + if ( length == 0 ) + return true; + + const QCString part = str.left( length ); + return (pattern == part); } -static void removeEscapes( QString &str ) +static void addEscapes( QCString &str ) { - str.replace( cr, "\\r" ); - str.replace( newline, "\n" ); - str.replace( comma, "," ); - str.replace( backslash, "\\" ); + str.replace( '\\', "\\\\" ); + str.replace( ',', "\\," ); + str.replace( '\r', "\\r" ); + str.replace( '\n', "\\n" ); +} + +static void removeEscapes( QCString &str ) +{ + str.replace( "\\r", "\r" ); + str.replace( "\\n", "\n" ); + str.replace( "\\,", "," ); + str.replace( "\\\\", "\\" ); } VCardParser::VCardParser() @@ -60,24 +98,29 @@ VCardParser::~VCardParser() VCard::List VCardParser::parseVCards( const QString& text ) { + return parseVCardsRaw( text.utf8() ); +} + +VCard::List VCardParser::parseVCardsRaw( const QCString& text ) +{ static QRegExp sep( "[\x0d\x0a]" ); VCard currentVCard; VCard::List vCardList; - QString currentLine; + QCString currentLine; - const QStringList lines = QStringList::split( sep, text ); - QStringList::ConstIterator it; + const QCStringList lines = splitCString( text, sep ); + QCStringList::ConstIterator it; bool inVCard = false; - QStringList::ConstIterator linesEnd( lines.end() ); + QCStringList::ConstIterator linesEnd( lines.end() ); for ( it = lines.begin(); it != linesEnd; ++it ) { if ( (*it).isEmpty() ) // empty line continue; if ( (*it)[ 0 ] == ' ' || (*it)[ 0 ] == '\t' ) { // folded line => append to previous - currentLine += QString( *it ).remove( 0, 1 ); + currentLine.append( (*it).mid( 1 ) ); continue; } else { if ( inVCard && !currentLine.isEmpty() ) { // now parse the line @@ -88,23 +131,23 @@ VCard::List VCardParser::parseVCards( co } VCardLine vCardLine; - const QString key = currentLine.left( colon ).stripWhiteSpace(); - QString value = currentLine.mid( colon + 1 ); + const QCString key = currentLine.left( colon ).stripWhiteSpace(); + QCString value = currentLine.mid( colon + 1 ); - QStringList params = QStringList::split( ';', key ); + QCStringList params = splitCString( key, ';' ); // check for group if ( params[0].find( '.' ) != -1 ) { - const QStringList groupList = QStringList::split( '.', params[0] ); - vCardLine.setGroup( groupList[0] ); - vCardLine.setIdentifier( groupList[1] ); + const QCStringList groupList = splitCString( params[0], '.' ); + vCardLine.setGroup( QString::fromLatin1( groupList[0] ) ); + vCardLine.setIdentifier( QString::fromLatin1( groupList[1] ) ); } else - vCardLine.setIdentifier( params[0] ); + vCardLine.setIdentifier( QString::fromLatin1( params[0] ) ); if ( params.count() > 1 ) { // find all parameters - QStringList::ConstIterator paramIt = params.begin(); + QCStringList::ConstIterator paramIt = params.begin(); for ( ++paramIt; paramIt != params.end(); ++paramIt ) { - QStringList pair = QStringList::split( '=', *paramIt ); + QCStringList pair = splitCString( *paramIt, '=' ); if ( pair.size() == 1 ) { // correct the fucking 2.1 'standard' if ( pair[0].lower() == "quoted-printable" ) { @@ -119,12 +162,12 @@ VCard::List VCardParser::parseVCards( co } // This is pretty much a faster pair[1].contains( ',' )... if ( pair[1].find( ',' ) != -1 ) { // parameter in type=x,y,z format - const QStringList args = QStringList::split( ',', pair[ 1 ] ); - QStringList::ConstIterator argIt; + const QCStringList args = splitCString( pair[ 1 ], ',' ); + QCStringList::ConstIterator argIt; for ( argIt = args.begin(); argIt != args.end(); ++argIt ) - vCardLine.addParameter( pair[0].lower(), *argIt ); + vCardLine.addParameter( QString::fromLatin1( pair[0].lower() ), QString::fromLatin1( *argIt ) ); } else - vCardLine.addParameter( pair[0].lower(), pair[1] ); + vCardLine.addParameter( QString::fromLatin1( pair[0].lower() ), QString::fromLatin1( pair[1] ) ); } } @@ -133,10 +176,8 @@ VCard::List VCardParser::parseVCards( co QByteArray output; bool wasBase64Encoded = false; - params = vCardLine.parameterList(); - if ( params.findIndex( "encoding" ) != -1 ) { // have to decode the data - QByteArray input; - input = QCString(value.latin1()); + if ( vCardLine.parameterList().findIndex( "encoding" ) != -1 ) { // have to decode the data + QByteArray input = value; if ( vCardLine.parameter( "encoding" ).lower() == "b" || vCardLine.parameter( "encoding" ).lower() == "base64" ) { KCodecs::base64Decode( input, output ); @@ -148,14 +189,14 @@ VCard::List VCardParser::parseVCards( co value = value.remove( value.length() - 1, 1 ) + (*it); ++it; } - input = QCString(value.latin1()); + input = value; KCodecs::quotedPrintableDecode( input, output ); } } else { - output = QCString(value.latin1()); + output = value; } - if ( params.findIndex( "charset" ) != -1 ) { // have to convert the data + if ( vCardLine.parameterList().findIndex( "charset" ) != -1 ) { // have to convert the data QTextCodec *codec = QTextCodec::codecForName( vCardLine.parameter( "charset" ).latin1() ); if ( codec ) { @@ -173,17 +214,17 @@ VCard::List VCardParser::parseVCards( co } // we do not save the start and end tag as vcardline - if ( (*it).lower().startsWith( "begin:vcard" ) ) { + if ( cStringStartsWith( (*it).lower(), QCString( "begin:vcard" ) ) ) { inVCard = true; - currentLine.setLength( 0 ); + currentLine = QCString(); currentVCard.clear(); // flush vcard continue; } - if ( (*it).lower().startsWith( "end:vcard" ) ) { + if ( cStringStartsWith( (*it).lower(), QCString( "end:vcard" ) ) ) { inVCard = false; vCardList.append( currentVCard ); - currentLine.setLength( 0 ); + currentLine = QCString(); currentVCard.clear(); // flush vcard continue; } @@ -197,8 +238,13 @@ VCard::List VCardParser::parseVCards( co QString VCardParser::createVCards( const VCard::List& list ) { - QString text; - QString textLine; + return QString::fromUtf8( createVCardsRaw( list ) ); +} + +QCString VCardParser::createVCardsRaw( const VCard::List& list ) +{ + QCString text; + QCString textLine; QString encodingType; QStringList idents; QStringList params; @@ -213,7 +259,7 @@ QString VCardParser::createVCards( const bool hasEncoding; - text.reserve( list.size() * 300 ); // reserve memory to be more efficient +// text.reserve( list.size() * 300 ); // reserve memory to be more efficient // iterate over the cards VCard::List::ConstIterator listEnd( list.end() ); @@ -228,9 +274,9 @@ QString VCardParser::createVCards( const for ( lineIt = lines.constBegin(); lineIt != lines.constEnd(); ++lineIt ) { if ( !(*lineIt).value().asString().isEmpty() ) { if ( (*lineIt).hasGroup() ) - textLine = (*lineIt).group() + "." + (*lineIt).identifier(); + textLine = (*lineIt).group().latin1() + QCString( "." ) + (*lineIt).identifier().latin1(); else - textLine = (*lineIt).identifier(); + textLine = (*lineIt).identifier().latin1(); params = (*lineIt).parameterList(); hasEncoding = false; @@ -243,9 +289,9 @@ QString VCardParser::createVCards( const values = (*lineIt).parameters( *paramIt ); for ( valueIt = values.constBegin(); valueIt != values.constEnd(); ++valueIt ) { - textLine.append( ";" + (*paramIt).upper() ); + textLine.append( QCString( ";" ) + (*paramIt).upper().latin1() ); if ( !(*valueIt).isEmpty() ) - textLine.append( "=" + (*valueIt) ); + textLine.append( QCString( "=" ) + (*valueIt).latin1() ); } } } @@ -261,11 +307,11 @@ QString VCardParser::createVCards( const KCodecs::quotedPrintableEncode( input, output, false ); } - QString value( output ); + QCString value( output ); addEscapes( value ); textLine.append( ":" + value ); } else { - QString value( (*lineIt).value().asString() ); + QCString value( (*lineIt).value().toString().utf8() ); addEscapes( value ); textLine.append( ":" + value ); } Index: kabc/vcardparser/vcardparser.h =================================================================== --- kabc/vcardparser/vcardparser.h.orig +++ kabc/vcardparser/vcardparser.h @@ -34,6 +34,9 @@ class VCardParser static VCard::List parseVCards( const QString& text ); static QString createVCards( const VCard::List& list ); + static VCard::List parseVCardsRaw( const QCString& text ); + static QCString createVCardsRaw( const VCard::List& list ); + private: class VCardParserPrivate; VCardParserPrivate *d; Index: kabc/vcardtool.cpp =================================================================== --- kabc/vcardtool.cpp.orig +++ kabc/vcardtool.cpp @@ -74,15 +74,28 @@ VCardTool::~VCardTool() { } -// TODO: make list a const& +QCString VCardTool::createVCardsRaw( Addressee::List list, VCard::Version version ) +{ + const VCard::List vCardList = createVCardsInternal( list, version ); + + return VCardParser::createVCardsRaw( vCardList ); +} + QString VCardTool::createVCards( Addressee::List list, VCard::Version version ) { - VCard::List vCardList; + const VCard::List vCardList = createVCardsInternal( list, version ); + + return VCardParser::createVCards( vCardList ); +} + +KABC::VCard::List VCardTool::createVCardsInternal( Addressee::List list, KABC::VCard::Version version ) +{ + KABC::VCard::List vCardList; Addressee::List::ConstIterator addrIt; Addressee::List::ConstIterator listEnd( list.constEnd() ); for ( addrIt = list.constBegin(); addrIt != listEnd; ++addrIt ) { - VCard card; + KABC::VCard card; QStringList::ConstIterator strIt; // ADR + LABEL @@ -348,17 +361,30 @@ QString VCardTool::createVCards( Address vCardList.append( card ); } - return VCardParser::createVCards( vCardList ); + return vCardList; +} + +Addressee::List VCardTool::parseVCardsRaw( const QCString& vcard ) +{ + const VCard::List vCardList = VCardParser::parseVCardsRaw( vcard ); + + return parseVCardsInternal( vCardList ); } Addressee::List VCardTool::parseVCards( const QString& vcard ) { + const VCard::List vCardList = VCardParser::parseVCards( vcard ); + + return parseVCardsInternal( vCardList ); +} + +Addressee::List VCardTool::parseVCardsInternal( const VCard::List &vCardList ) +{ static const QChar semicolonSep( ';' ); static const QChar commaSep( ',' ); QString identifier; Addressee::List addrList; - const VCard::List vCardList = VCardParser::parseVCards( vcard ); VCard::List::ConstIterator cardIt; VCard::List::ConstIterator listEnd( vCardList.end() ); Index: kabc/vcardtool.h =================================================================== --- kabc/vcardtool.h.orig +++ kabc/vcardtool.h @@ -46,12 +46,19 @@ class KABC_EXPORT VCardTool */ QString createVCards( Addressee::List list, VCard::Version version = VCard::v3_0 ); + QCString createVCardsRaw( Addressee::List list, VCard::Version version = VCard::v3_0 ); + /** Parses the string and returns a list of addressee objects. */ Addressee::List parseVCards( const QString& vcard ); + Addressee::List parseVCardsRaw( const QCString& vcard ); + private: + VCard::List createVCardsInternal( Addressee::List list, VCard::Version version ); + Addressee::List parseVCardsInternal( const VCard::List &vCardList ); + /** Split a string and replaces escaped separators on the fly with unescaped ones.