Index: kabc/vcardformatplugin.cpp
================================================================================
--- kabc/vcardconverter.cpp
+++ kabc/vcardconverter.cpp
@@ -51,6 +51,14 @@
   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 @@
   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 @@
   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 @@
   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 )
--- kabc/vcardconverter.h
+++ kabc/vcardconverter.h
@@ -82,6 +82,7 @@
       @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 @@
      */
     // 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 @@
       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 )"
 
--- kabc/vcardformatplugin.cpp
+++ kabc/vcardformatplugin.cpp
@@ -38,14 +38,11 @@
 
 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::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 @@
 
   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 @@
     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
--- kabc/vcardparser/vcardparser.cpp
+++ 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 @@
 
 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 @@
         }
 
         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 @@
             }
             // 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 @@
         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 @@
               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 @@
       }
 
       // 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 @@
 
 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 @@
 
   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 @@
       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 @@
 
               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 @@
               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 );
           }
--- kabc/vcardparser/vcardparser.h
+++ kabc/vcardparser/vcardparser.h
@@ -34,6 +34,9 @@
     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;
--- kabc/vcardtool.cpp
+++ kabc/vcardtool.cpp
@@ -74,15 +74,28 @@
 {
 }
 
-// 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 @@
     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() );
--- kabc/vcardtool.h
+++ kabc/vcardtool.h
@@ -46,12 +46,19 @@
      */
     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.
