Key VCardTool::parseKey(const VCardLine &line) { Key key; const QStringList params = line.parameterList(); if(params.findIndex("encoding") != -1) key.setBinaryData(line.value().asByteArray()); else key.setTextData(line.value().asString()); if(params.findIndex("type") != -1) { if(line.parameter("type").lower() == "x509") key.setType(Key::X509); else if(line.parameter("type").lower() == "pgp") key.setType(Key::PGP); else { key.setType(Key::Custom); key.setCustomTypeString(line.parameter("type")); } } return key; }
Agent VCardTool::parseAgent(const VCardLine &line) { Agent agent; const QStringList params = line.parameterList(); if(params.findIndex("value") != -1) { if(line.parameter("value").lower() == "uri") agent.setUrl(line.value().asString()); } else { QString str = line.value().asString(); str.replace("\\n", "\r\n"); str.replace("\\N", "\r\n"); str.replace("\\;", ";"); str.replace("\\:", ":"); str.replace("\\,", ","); const Addressee::List list = parseVCards(str); if(list.count() > 0) { Addressee *addr = new Addressee; *addr = list[0]; agent.setAddressee(addr); } } return agent; }
Picture VCardTool::parsePicture(const VCardLine &line) { Picture pic; const QStringList params = line.parameterList(); if(params.findIndex("encoding") != -1) { QImage img; img.loadFromData(line.value().asByteArray()); pic.setData(img); } else if(params.findIndex("value") != -1) { if(line.parameter("value").lower() == "uri") pic.setUrl(line.value().asString()); } if(params.findIndex("type") != -1) pic.setType(line.parameter("type")); return pic; }
Sound VCardTool::parseSound(const VCardLine &line) { Sound snd; const QStringList params = line.parameterList(); if(params.findIndex("encoding") != -1) snd.setData(line.value().asByteArray()); else if(params.findIndex("value") != -1) { if(line.parameter("value").lower() == "uri") snd.setUrl(line.value().asString()); } /* TODO: support sound types if ( params.contains( "type" ) ) snd.setType( line.parameter( "type" ) ); */ return snd; }
VCard::List VCardParser::parseVCards( const QByteArray &text ) { VCard currentVCard; VCard::List vCardList; QByteArray currentLine; QList<QByteArray> lines = text.split( '\n' ); bool inVCard = false; QList<QByteArray>::Iterator it( lines.begin() ); QList<QByteArray>::Iterator linesEnd( lines.end() ); for ( ; it != linesEnd; ++it ) { // remove the trailing \r, left from \r\n if ( ( *it ).endsWith( '\r' ) ) { ( *it ).chop( 1 ); } if ( ( *it ).startsWith( ' ' ) || ( *it ).startsWith( '\t' ) ) { //folded line => append to previous currentLine.append( ( *it ).mid( 1 ) ); continue; } else { if ( ( *it ).trimmed().isEmpty() ) { // empty line continue; } if ( inVCard && !currentLine.isEmpty() ) { // now parse the line int colon = currentLine.indexOf( ':' ); if ( colon == -1 ) { // invalid line currentLine = ( *it ); continue; } VCardLine vCardLine; const QByteArray key = currentLine.left( colon ).trimmed(); QByteArray value = currentLine.mid( colon + 1 ); QList<QByteArray> params = key.split( ';' ); // check for group int groupPos = params[ 0 ].indexOf( '.' ); if ( groupPos != -1 ) { vCardLine.setGroup( QString::fromLatin1( params[ 0 ].left( groupPos ) ) ); vCardLine.setIdentifier( QString::fromLatin1( params[ 0 ].mid( groupPos + 1 ) ) ); } else { vCardLine.setIdentifier( QString::fromLatin1( params[ 0 ] ) ); } if ( params.count() > 1 ) { // find all parameters QList<QByteArray>::ConstIterator paramIt( params.constBegin() ); for ( ++paramIt; paramIt != params.constEnd(); ++paramIt ) { QList<QByteArray> pair = ( *paramIt ).split( '=' ); if ( pair.count() == 1 ) { // correct the f*****g 2.1 'standard' if ( pair[ 0 ].toLower() == "quoted-printable" ) { pair[ 0 ] = "encoding"; pair.append( "quoted-printable" ); } else if ( pair[ 0 ].toLower() == "base64" ) { pair[ 0 ] = "encoding"; pair.append( "base64" ); } else { pair.prepend( "type" ); } } if ( pair[ 1 ].indexOf( ',' ) != -1 ) { // parameter in type=x,y,z format const QList<QByteArray> args = pair[ 1 ].split( ',' ); QList<QByteArray>::ConstIterator argIt; QList<QByteArray>::ConstIterator argEnd( args.constEnd() ); for ( argIt = args.constBegin(); argIt != argEnd; ++argIt ) { vCardLine.addParameter( QString::fromLatin1( pair[ 0 ].toLower() ), QString::fromLatin1( *argIt ) ); } } else { vCardLine.addParameter( QString::fromLatin1( pair[ 0 ].toLower() ), QString::fromLatin1( pair[ 1 ] ) ); } } } removeEscapes( value ); QByteArray output; bool wasBase64Encoded = false; if ( vCardLine.parameterList().contains( QLatin1String( "encoding" ) ) ) { const QString encoding = vCardLine.parameter( QLatin1String( "encoding" ) ).toLower(); // have to decode the data if ( encoding == QLatin1String( "b" ) || encoding == QLatin1String( "base64" ) ) { output = QByteArray::fromBase64( value ); wasBase64Encoded = true; } else if ( encoding == QLatin1String( "quoted-printable" ) ) { // join any qp-folded lines while ( value.endsWith( '=' ) && it != linesEnd ) { value.chop( 1 ); // remove the '=' value.append( *it ); ++it; } KCodecs::quotedPrintableDecode( value, output ); } else if ( encoding == QLatin1String( "8bit" ) ) { output = value; } else { qDebug( "Unknown vcard encoding type!" ); } } else { output = value; } if ( vCardLine.parameterList().contains( QLatin1String( "charset" ) ) ) { // have to convert the data QTextCodec *codec = QTextCodec::codecForName( vCardLine.parameter( QLatin1String( "charset" ) ).toLatin1() ); if ( codec ) { vCardLine.setValue( codec->toUnicode( output ) ); } else { vCardLine.setValue( QString::fromUtf8( output ) ); } } else if ( wasBase64Encoded ) { vCardLine.setValue( output ); } else { vCardLine.setValue( QString::fromUtf8( output ) ); } currentVCard.addLine( vCardLine ); } // we do not save the start and end tag as vcardline if ( ( *it ).toLower().startsWith( "begin:vcard" ) ) { //krazy:exclude=strings inVCard = true; currentLine.clear(); currentVCard.clear(); // flush vcard continue; } if ( ( *it ).toLower().startsWith( "end:vcard" ) ) { //krazy:exclude=strings inVCard = false; vCardList.append( currentVCard ); currentLine.clear(); currentVCard.clear(); // flush vcard continue; } currentLine = ( *it ); } } return vCardList; }
VCard::List VCardParser::parseVCards( const QString& text ) { static QRegExp sep( "[\x0d\x0a]" ); VCard currentVCard; VCard::List vCardList; QString currentLine; const QStringList lines = QStringList::split( sep, text ); QStringList::ConstIterator it; bool inVCard = false; QStringList::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 ); continue; } else { if ( inVCard && !currentLine.isEmpty() ) { // now parse the line int colon = currentLine.find( ':' ); if ( colon == -1 ) { // invalid line currentLine = (*it); continue; } VCardLine vCardLine; const QString key = currentLine.left( colon ).stripWhiteSpace(); QString value = currentLine.mid( colon + 1 ); QStringList params = QStringList::split( ';', key ); // check for group if ( params[0].find( '.' ) != -1 ) { const QStringList groupList = QStringList::split( '.', params[0] ); vCardLine.setGroup( groupList[0] ); vCardLine.setIdentifier( groupList[1] ); } else vCardLine.setIdentifier( params[0] ); if ( params.count() > 1 ) { // find all parameters QStringList::ConstIterator paramIt = params.begin(); for ( ++paramIt; paramIt != params.end(); ++paramIt ) { QStringList pair = QStringList::split( '=', *paramIt ); if ( pair.size() == 1 ) { // correct the f*****g 2.1 'standard' if ( pair[0].lower() == "quoted-printable" ) { pair[0] = "encoding"; pair[1] = "quoted-printable"; } else if ( pair[0].lower() == "base64" ) { pair[0] = "encoding"; pair[1] = "base64"; } else { pair.prepend( "type" ); } } // 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; for ( argIt = args.begin(); argIt != args.end(); ++argIt ) vCardLine.addParameter( pair[0].lower(), *argIt ); } else vCardLine.addParameter( pair[0].lower(), pair[1] ); } } removeEscapes( value ); 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.parameter( "encoding" ).lower() == "b" || vCardLine.parameter( "encoding" ).lower() == "base64" ) { KCodecs::base64Decode( input, output ); wasBase64Encoded = true; } else if ( vCardLine.parameter( "encoding" ).lower() == "quoted-printable" ) { // join any qp-folded lines while ( value.at( value.length() - 1 ) == '=' && it != linesEnd ) { value = value.remove( value.length() - 1, 1 ) + (*it); ++it; } input = QCString(value.latin1()); KCodecs::quotedPrintableDecode( input, output ); } } else { output = QCString(value.latin1()); } if ( params.findIndex( "charset" ) != -1 ) { // have to convert the data QTextCodec *codec = QTextCodec::codecForName( vCardLine.parameter( "charset" ).latin1() ); if ( codec ) { vCardLine.setValue( codec->toUnicode( output ) ); } else { vCardLine.setValue( QString::fromUtf8( output ) ); } } else if ( wasBase64Encoded ) { vCardLine.setValue( output ); } else { // if charset not given, assume it's in UTF-8 (as used in previous KDE versions) vCardLine.setValue( QString::fromUtf8( output ) ); } currentVCard.addLine( vCardLine ); } // we do not save the start and end tag as vcardline if ( (*it).lower().startsWith( "begin:vcard" ) ) { inVCard = true; currentLine.setLength( 0 ); currentVCard.clear(); // flush vcard continue; } if ( (*it).lower().startsWith( "end:vcard" ) ) { inVCard = false; vCardList.append( currentVCard ); currentLine.setLength( 0 ); currentVCard.clear(); // flush vcard continue; } currentLine = (*it); } } return vCardList; }