kabc Library API Documentation

vcardparser.cpp

00001 /* 00002 This file is part of libkabc. 00003 Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 Boston, MA 02111-1307, USA. 00019 */ 00020 00021 #include <qregexp.h> 00022 00023 #include <kmdcodec.h> 00024 00025 #include "vcardparser.h" 00026 00027 #define FOLD_WIDTH 75 00028 00029 using namespace KABC; 00030 00031 VCardParser::VCardParser() 00032 { 00033 } 00034 00035 VCardParser::~VCardParser() 00036 { 00037 } 00038 00039 VCard::List VCardParser::parseVCards( const QString& text ) 00040 { 00041 VCard currentVCard; 00042 VCard::List vCardList; 00043 QString currentLine; 00044 00045 QStringList lines = QStringList::split( QRegExp( "[\x0d\x0a]" ), text ); 00046 QStringList::Iterator it; 00047 00048 bool inVCard = false; 00049 for ( it = lines.begin(); it != lines.end(); ++it ) { 00050 00051 if ( (*it).isEmpty() ) // empty line 00052 continue; 00053 00054 if ( (*it)[ 0 ] == ' ' || (*it)[ 0 ] == '\t' ) { // folded line => append to previous 00055 currentLine += (*it).remove( 0, 1 ); 00056 continue; 00057 } else { 00058 if ( inVCard && !currentLine.isEmpty() ) { // now parse the line 00059 int colon = currentLine.find( ':' ); 00060 if ( colon == -1 ) { // invalid line 00061 currentLine = (*it); 00062 continue; 00063 } 00064 00065 VCardLine vCardLine; 00066 QString key = currentLine.left( colon ).stripWhiteSpace(); 00067 QString value = currentLine.mid( colon + 1 ); 00068 00069 QStringList params = QStringList::split( ';', key ); 00070 vCardLine.setIdentifier( params[0] ); 00071 if ( params.count() > 1 ) { // find all parameters 00072 for ( uint i = 1; i < params.count(); ++i ) { 00073 QStringList pair = QStringList::split( '=', params[i] ); 00074 if ( pair.size() == 1 ) { 00075 // correct the fucking 2.1 'standard' 00076 if ( pair[0].lower() == "quoted-printable" ) { 00077 pair[0] = "encoding"; 00078 pair[1] = "quoted-printable"; 00079 } else { 00080 pair.prepend( "type" ); 00081 } 00082 } 00083 //This is pretty much a faster pair[1].contains( ',' )... 00084 if ( pair[1].find( ',' ) != -1 ) { // parameter in type=x,y,z format 00085 QStringList args = QStringList::split( ',', pair[ 1 ] ); 00086 for ( uint j = 0; j < args.count(); ++j ) 00087 vCardLine.addParameter( pair[0].lower(), args[j] ); 00088 } else 00089 vCardLine.addParameter( pair[0].lower(), pair[1] ); 00090 } 00091 } 00092 00093 params = vCardLine.parameterList(); 00094 if ( params.findIndex( "encoding" ) != -1 ) { // have to decode the data 00095 QByteArray input, output; 00096 input = value.local8Bit(); 00097 if ( vCardLine.parameter( "encoding" ).lower() == "b" || 00098 vCardLine.parameter( "encoding" ).lower() == "base64" ) 00099 KCodecs::base64Decode( input, output ); 00100 else if ( vCardLine.parameter( "encoding" ).lower() == "quoted-printable" ) 00101 KCodecs::quotedPrintableDecode( input, output ); 00102 00103 if ( vCardLine.parameter( "charset" ).lower() == "utf-8" ) { 00104 vCardLine.setValue( QString::fromUtf8( output.data(), output.size() ) ); 00105 } else { 00106 vCardLine.setValue( output ); 00107 } 00108 } else if ( vCardLine.parameter( "charset" ).lower() == "utf-8" ) { 00109 vCardLine.setValue( QString::fromUtf8( value.ascii() ) ); 00110 } else 00111 vCardLine.setValue( value.replace( "\\n", "\n" ) ); 00112 00113 currentVCard.addLine( vCardLine ); 00114 } 00115 00116 // we do not save the start and end tag as vcardline 00117 if ( (*it).lower().startsWith( "begin:vcard" ) ) { 00118 inVCard = true; 00119 currentLine.setLength( 0 ); 00120 currentVCard.clear(); // flush vcard 00121 continue; 00122 } 00123 00124 if ( (*it).lower().startsWith( "end:vcard" ) ) { 00125 inVCard = false; 00126 vCardList.append( currentVCard ); 00127 currentLine.setLength( 0 ); 00128 currentVCard.clear(); // flush vcard 00129 continue; 00130 } 00131 00132 currentLine = (*it); 00133 } 00134 } 00135 00136 return vCardList; 00137 } 00138 00139 QString VCardParser::createVCards( const VCard::List& list ) 00140 { 00141 QString text; 00142 QString textLine; 00143 QString encodingType; 00144 QStringList idents; 00145 QStringList params; 00146 QStringList values; 00147 QStringList::ConstIterator identIt; 00148 QStringList::Iterator paramIt; 00149 QStringList::Iterator valueIt; 00150 00151 VCardLine::List lines; 00152 VCardLine::List::Iterator lineIt; 00153 VCard::List::ConstIterator cardIt; 00154 00155 bool hasEncoding; 00156 00157 00158 // iterate over the cards 00159 for ( cardIt = list.begin(); cardIt != list.end(); ++cardIt ) { 00160 text.append( "BEGIN:VCARD\r\n" ); 00161 00162 idents = (*cardIt).identifiers(); 00163 for ( identIt = idents.begin(); identIt != idents.end(); ++identIt ) { 00164 VCard card = (*cardIt); 00165 lines = card.lines( (*identIt) ); 00166 00167 // iterate over the lines 00168 for ( lineIt = lines.begin(); lineIt != lines.end(); ++lineIt ) { 00169 if ( !(*lineIt).value().asString().isEmpty() ) { 00170 textLine = (*lineIt).identifier(); 00171 00172 params = (*lineIt).parameterList(); 00173 hasEncoding = false; 00174 if ( params.count() > 0 ) { // we have parameters 00175 for ( paramIt = params.begin(); paramIt != params.end(); ++paramIt ) { 00176 if ( (*paramIt) == "encoding" ) { 00177 hasEncoding = true; 00178 encodingType = (*lineIt).parameter( "encoding" ).lower(); 00179 } 00180 00181 values = (*lineIt).parameters( *paramIt ); 00182 for ( valueIt = values.begin(); valueIt != values.end(); ++valueIt ) { 00183 textLine.append( ";" + (*paramIt).upper() ); 00184 if ( !(*valueIt).isEmpty() ) 00185 textLine.append( "=" + (*valueIt) ); 00186 } 00187 } 00188 } 00189 00190 if ( hasEncoding ) { // have to encode the data 00191 QByteArray input, output; 00192 input = (*lineIt).value().toByteArray(); 00193 if ( encodingType == "b" ) 00194 KCodecs::base64Encode( input, output ); 00195 else if ( encodingType == "quoted-printable" ) 00196 KCodecs::quotedPrintableEncode( input, output ); 00197 textLine.append( ":" + QString( output ) ); 00198 } else 00199 textLine.append( ":" + (*lineIt).value().asString().replace( "\n", "\\n" ) ); 00200 00201 if ( textLine.length() > FOLD_WIDTH ) { // we have to fold the line 00202 for ( uint i = 0; i <= ( textLine.length() / FOLD_WIDTH ); ++i ) 00203 text.append( ( i == 0 ? "" : " " ) + textLine.mid( i * FOLD_WIDTH, FOLD_WIDTH ) + "\r\n" ); 00204 } else 00205 text.append( textLine + "\r\n" ); 00206 } 00207 } 00208 } 00209 00210 text.append( "END:VCARD\r\n" ); 00211 text.append( "\r\n" ); 00212 } 00213 00214 return text; 00215 }
KDE Logo
This file is part of the documentation for kabc Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 10 18:56:01 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003