virtual void handleVCard( const JID& jid, const VCard *v ) { ++m_count; if( !v ) { printf( "empty vcard!\n" ); return; } VCard* vcard = new VCard( *v ); printf( "received vcard for %s: %s, %d\n", jid.full().c_str(), vcard->tag()->xml().c_str(), m_count ); VCard::AddressList::const_iterator it = vcard->addresses().begin(); for( ; it != vcard->addresses().end(); ++it ) { printf( "address: %s\n", (*it).street.c_str() ); } if( m_count > 2 ) j->disconnect(); else if( m_count == 1 ) { VCard *v = new VCard(); v->setFormattedname( "Hurk the Hurk" ); v->setNickname( "hurkhurk" ); v->setName( "Simpson", "Bart", "", "Mr.", "jr." ); v->addAddress( "pobox", "app. 2", "street", "Springfield", "region", "123", "USA", VCard::AddrTypeHome ); m_vManager->storeVCard( v, this ); printf( "setting vcard: %s\n", v->tag()->xml().c_str() ); } else { JID jid( "*****@*****.**" ); m_vManager->fetchVCard( jid, this ); } }
int main (int argc, char *argv[]) { QApplication app(argc, argv); VCard vcard; const VCard *vc2 = VCardFactory::vcard("*****@*****.**"); if ( vc2 ) vcard = *vc2; QFile file2 ( "vcard-out.xml" ); file2.open ( IO_WriteOnly ); QTextStream out ( &file2 ); QDomDocument doc2; doc2.appendChild( vcard.toXml ( &doc2 ) ); out << doc2.toString(8); if ( vcard.isEmpty() ) qWarning("VCard is empty!!!"); qWarning ( "%s", doc2.toString(8).latin1() );*/ return 0; }
VCard GetVCard::createVCardFromXmppFormat(QXmppVCardIq card) { VCard vCard; vCard.setId(card.id()); vCard.setStatus(card.description()); vCard.setAvatar(createImageFromBytes(card.photo())); return vCard; }
void testParse_Nickname() { PayloadsParserTester parser; CPPUNIT_ASSERT(parser.parse( "<vCard xmlns='vcard-temp'>" "<NICKNAME>mynick</NICKNAME>" "</vCard>")); VCard* payload = dynamic_cast<VCard*>(parser.getPayload().get()); CPPUNIT_ASSERT_EQUAL(std::string("mynick"), payload->getNickname()); }
int main( int /*argc*/, char** /*argv*/ ) { int fail = 0; std::string name; Tag *t; // ------- { name = "empty vcard request"; VCard v; t = v.tag(); if( !t || t->xml() != "<vCard xmlns='" + XMLNS_VCARD_TEMP + "' version='3.0'/>" ) { ++fail; printf( "test '%s' failed\n", name.c_str() ); } delete t; t = 0; } // ------- name = "VCard/SEFactory test"; StanzaExtensionFactory sef; sef.registerExtension( new VCard() ); Tag* f = new Tag( "iq" ); new Tag( f, "vCard", "xmlns", XMLNS_VCARD_TEMP ); IQ iq( IQ::Set, JID(), "" ); sef.addExtensions( iq, f ); const VCard* se = iq.findExtension<VCard>( ExtVCard ); if( se == 0 ) { ++fail; printf( "test '%s' failed\n", name.c_str() ); } delete f; printf( "VCard: " ); if( fail == 0 ) { printf( "OK\n" ); return 0; } else { printf( "%d test(s) failed\n", fail ); return 1; } }
void YaProfile::setAvatar(QPixmap avatar) { const VCard* profileVCard = VCardFactory::instance()->vcard(jid()); VCard vcard; if (profileVCard) vcard = *profileVCard; QByteArray ba; QBuffer buffer(&ba); buffer.open(QIODevice::WriteOnly); avatar.save(&buffer, "PNG"); // TODO: maybe consider using different format? vcard.setPhoto(ba); const PsiAccount* a = account(); const VCard v = vcard; VCardFactory::instance()->setVCard(a, v); }
void testParse_Photo() { PayloadsParserTester parser; CPPUNIT_ASSERT(parser.parse( "<vCard xmlns='vcard-temp'>" "<PHOTO>" "<TYPE>image/jpeg</TYPE>" "<BINVAL>" "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ej" "EyMzQ1Njc4OTA=" "</BINVAL>" "</PHOTO>" "</vCard>")); VCard* payload = dynamic_cast<VCard*>(parser.getPayload().get()); CPPUNIT_ASSERT_EQUAL(std::string("image/jpeg"), payload->getPhotoType()); CPPUNIT_ASSERT_EQUAL(ByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"), payload->getPhoto()); }
/** * \brief Call this, when you need a cached vCard. */ const VCard* VCardFactory::vcard(const Jid &j) { // first, try to get vCard from runtime cache if (vcardDict_.contains(j.userHost())) { return vcardDict_[j.userHost()]; } // then try to load from cache on disk QFile file ( vCardsDir_ + "/" + JIDUtil::encode(j.userHost()).lower() + ".xml" ); file.open (QIODevice::ReadOnly); QDomDocument doc; VCard *vcard = new VCard; if ( doc.setContent(&file, false) ) { vcard->fromXml( doc.documentElement() ); checkLimit(j.userHost(), vcard); return vcard; } delete vcard; return 0; }
void VCardFactory::taskFinished() { JT_VCard *task = (JT_VCard *)sender(); if ( task->success() ) { Jid j = task->jid(); VCard *vcard = new VCard; *vcard = task->vcard(); checkLimit(j.userHost(), vcard); // save vCard to disk QFile file ( vCardsDir_ + "/" + JIDUtil::encode(j.userHost()).lower() + ".xml" ); file.open ( QIODevice::WriteOnly ); QTextStream out ( &file ); out.setEncoding ( QTextStream::UnicodeUTF8 ); QDomDocument doc; doc.appendChild( vcard->toXml ( &doc ) ); out << doc.toString(4); emit vcardChanged(j); } }
// TODO: make list a const& QString VCardTool::createVCards(Addressee::List list, VCard::Version version) { VCard::List vCardList; Addressee::List::ConstIterator addrIt; Addressee::List::ConstIterator listEnd(list.constEnd()); for(addrIt = list.constBegin(); addrIt != listEnd; ++addrIt) { VCard card; QStringList::ConstIterator strIt; // ADR + LABEL const Address::List addresses = (*addrIt).addresses(); for(Address::List::ConstIterator it = addresses.begin(); it != addresses.end(); ++it) { QStringList address; bool isEmpty = ((*it).postOfficeBox().isEmpty() && (*it).extended().isEmpty() && (*it).street().isEmpty() && (*it).locality().isEmpty() && (*it).region().isEmpty() && (*it).postalCode().isEmpty() && (*it).country().isEmpty()); address.append((*it).postOfficeBox().replace(';', "\\;")); address.append((*it).extended().replace(';', "\\;")); address.append((*it).street().replace(';', "\\;")); address.append((*it).locality().replace(';', "\\;")); address.append((*it).region().replace(';', "\\;")); address.append((*it).postalCode().replace(';', "\\;")); address.append((*it).country().replace(';', "\\;")); VCardLine adrLine("ADR", address.join(";")); if(version == VCard::v2_1 && needsEncoding(address.join(";"))) { adrLine.addParameter("charset", "UTF-8"); adrLine.addParameter("encoding", "QUOTED-PRINTABLE"); } VCardLine labelLine("LABEL", (*it).label()); if(version == VCard::v2_1 && needsEncoding((*it).label())) { labelLine.addParameter("charset", "UTF-8"); labelLine.addParameter("encoding", "QUOTED-PRINTABLE"); } bool hasLabel = !(*it).label().isEmpty(); QMap< QString, int >::ConstIterator typeIt; for(typeIt = mAddressTypeMap.constBegin(); typeIt != mAddressTypeMap.constEnd(); ++typeIt) { if(typeIt.data() & (*it).type()) { adrLine.addParameter("TYPE", typeIt.key()); if(hasLabel) labelLine.addParameter("TYPE", typeIt.key()); } } if(!isEmpty) card.addLine(adrLine); if(hasLabel) card.addLine(labelLine); } // AGENT card.addLine(createAgent(version, (*addrIt).agent())); // BDAY card.addLine(VCardLine("BDAY", createDateTime((*addrIt).birthday()))); // CATEGORIES if(version == VCard::v3_0) { QStringList categories = (*addrIt).categories(); QStringList::Iterator catIt; for(catIt = categories.begin(); catIt != categories.end(); ++catIt) (*catIt).replace(',', "\\,"); VCardLine catLine("CATEGORIES", categories.join(",")); if(version == VCard::v2_1 && needsEncoding(categories.join(","))) { catLine.addParameter("charset", "UTF-8"); catLine.addParameter("encoding", "QUOTED-PRINTABLE"); } card.addLine(catLine); } // CLASS if(version == VCard::v3_0) { card.addLine(createSecrecy((*addrIt).secrecy())); } // EMAIL const QStringList emails = (*addrIt).emails(); bool pref = true; for(strIt = emails.begin(); strIt != emails.end(); ++strIt) { VCardLine line("EMAIL", *strIt); if(pref == true && emails.count() > 1) { line.addParameter("TYPE", "PREF"); pref = false; } card.addLine(line); } // FN VCardLine fnLine("FN", (*addrIt).formattedName()); if(version == VCard::v2_1 && needsEncoding((*addrIt).formattedName())) { fnLine.addParameter("charset", "UTF-8"); fnLine.addParameter("encoding", "QUOTED-PRINTABLE"); } card.addLine(fnLine); // GEO Geo geo = (*addrIt).geo(); if(geo.isValid()) { QString str; str.sprintf("%.6f;%.6f", geo.latitude(), geo.longitude()); card.addLine(VCardLine("GEO", str)); } // KEY const Key::List keys = (*addrIt).keys(); Key::List::ConstIterator keyIt; for(keyIt = keys.begin(); keyIt != keys.end(); ++keyIt) card.addLine(createKey(*keyIt)); // LOGO card.addLine(createPicture("LOGO", (*addrIt).logo())); // MAILER VCardLine mailerLine("MAILER", (*addrIt).mailer()); if(version == VCard::v2_1 && needsEncoding((*addrIt).mailer())) { mailerLine.addParameter("charset", "UTF-8"); mailerLine.addParameter("encoding", "QUOTED-PRINTABLE"); } card.addLine(mailerLine); // N QStringList name; name.append((*addrIt).familyName().replace(';', "\\;")); name.append((*addrIt).givenName().replace(';', "\\;")); name.append((*addrIt).additionalName().replace(';', "\\;")); name.append((*addrIt).prefix().replace(';', "\\;")); name.append((*addrIt).suffix().replace(';', "\\;")); VCardLine nLine("N", name.join(";")); if(version == VCard::v2_1 && needsEncoding(name.join(";"))) { nLine.addParameter("charset", "UTF-8"); nLine.addParameter("encoding", "QUOTED-PRINTABLE"); } card.addLine(nLine); // NAME VCardLine nameLine("NAME", (*addrIt).name()); if(version == VCard::v2_1 && needsEncoding((*addrIt).name())) { nameLine.addParameter("charset", "UTF-8"); nameLine.addParameter("encoding", "QUOTED-PRINTABLE"); } card.addLine(nameLine); // NICKNAME if(version == VCard::v3_0) card.addLine(VCardLine("NICKNAME", (*addrIt).nickName())); // NOTE VCardLine noteLine("NOTE", (*addrIt).note()); if(version == VCard::v2_1 && needsEncoding((*addrIt).note())) { noteLine.addParameter("charset", "UTF-8"); noteLine.addParameter("encoding", "QUOTED-PRINTABLE"); } card.addLine(noteLine); // ORG QStringList organization; organization.append((*addrIt).organization().replace(';', "\\;")); if(!(*addrIt).department().isEmpty()) organization.append((*addrIt).department().replace(';', "\\;")); VCardLine orgLine("ORG", organization.join(";")); if(version == VCard::v2_1 && needsEncoding(organization.join(";"))) { orgLine.addParameter("charset", "UTF-8"); orgLine.addParameter("encoding", "QUOTED-PRINTABLE"); } card.addLine(orgLine); // PHOTO card.addLine(createPicture("PHOTO", (*addrIt).photo())); // PROID if(version == VCard::v3_0) card.addLine(VCardLine("PRODID", (*addrIt).productId())); // REV card.addLine(VCardLine("REV", createDateTime((*addrIt).revision()))); // ROLE VCardLine roleLine("ROLE", (*addrIt).role()); if(version == VCard::v2_1 && needsEncoding((*addrIt).role())) { roleLine.addParameter("charset", "UTF-8"); roleLine.addParameter("encoding", "QUOTED-PRINTABLE"); } card.addLine(roleLine); // SORT-STRING if(version == VCard::v3_0) card.addLine(VCardLine("SORT-STRING", (*addrIt).sortString())); // SOUND card.addLine(createSound((*addrIt).sound())); // TEL const PhoneNumber::List phoneNumbers = (*addrIt).phoneNumbers(); PhoneNumber::List::ConstIterator phoneIt; for(phoneIt = phoneNumbers.begin(); phoneIt != phoneNumbers.end(); ++phoneIt) { VCardLine line("TEL", (*phoneIt).number()); QMap< QString, int >::ConstIterator typeIt; for(typeIt = mPhoneTypeMap.constBegin(); typeIt != mPhoneTypeMap.constEnd(); ++typeIt) { if(typeIt.data() & (*phoneIt).type()) line.addParameter("TYPE", typeIt.key()); } card.addLine(line); } // TITLE VCardLine titleLine("TITLE", (*addrIt).title()); if(version == VCard::v2_1 && needsEncoding((*addrIt).title())) { titleLine.addParameter("charset", "UTF-8"); titleLine.addParameter("encoding", "QUOTED-PRINTABLE"); } card.addLine(titleLine); // TZ TimeZone timeZone = (*addrIt).timeZone(); if(timeZone.isValid()) { QString str; int neg = 1; if(timeZone.offset() < 0) neg = -1; str.sprintf("%c%02d:%02d", (timeZone.offset() >= 0 ? '+' : '-'), (timeZone.offset() / 60) * neg, (timeZone.offset() % 60) * neg); card.addLine(VCardLine("TZ", str)); } // UID card.addLine(VCardLine("UID", (*addrIt).uid())); // URL card.addLine(VCardLine("URL", (*addrIt).url().url())); // VERSION if(version == VCard::v2_1) card.addLine(VCardLine("VERSION", "2.1")); if(version == VCard::v3_0) card.addLine(VCardLine("VERSION", "3.0")); // X- const QStringList customs = (*addrIt).customs(); for(strIt = customs.begin(); strIt != customs.end(); ++strIt) { QString identifier = "X-" + (*strIt).left((*strIt).find(":")); QString value = (*strIt).mid((*strIt).find(":") + 1); if(value.isEmpty()) continue; VCardLine line(identifier, value); if(version == VCard::v2_1 && needsEncoding(value)) { line.addParameter("charset", "UTF-8"); line.addParameter("encoding", "QUOTED-PRINTABLE"); } card.addLine(line); } vCardList.append(card); } return VCardParser::createVCards(vCardList); }
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; }
bool VCard::fromXml(const QDomElement &q) { if ( q.tagName().toUpper() != "VCARD" ) return false; QDomNode n = q.firstChild(); for ( ; !n.isNull(); n = n.nextSibling() ) { QDomElement i = n.toElement(); if ( i.isNull() ) continue; QString tag = i.tagName().toUpper(); bool found; QDomElement e; if ( tag == "VERSION" ) d->version = i.text().trimmed(); else if ( tag == "FN" ) d->fullName = i.text().trimmed(); else if ( tag == "N" ) { d->familyName = subTagText(i, "FAMILY"); d->givenName = subTagText(i, "GIVEN"); d->middleName = subTagText(i, "MIDDLE"); d->prefixName = subTagText(i, "PREFIX"); d->suffixName = subTagText(i, "SUFFIX"); } else if ( tag == "NICKNAME" ) d->nickName = i.text().trimmed(); else if ( tag == "PHOTO" ) { d->photo = QCA::Base64().stringToArray(subTagText(i, "BINVAL").replace("\n","")).toByteArray(); d->photoURI = subTagText(i, "EXTVAL"); } else if ( tag == "BDAY" ) d->bday = i.text().trimmed(); else if ( tag == "ADR" ) { Address a; a.home = hasSubTag(i, "HOME"); a.work = hasSubTag(i, "WORK"); a.postal = hasSubTag(i, "POSTAL"); a.parcel = hasSubTag(i, "PARCEL"); a.dom = hasSubTag(i, "DOM"); a.intl = hasSubTag(i, "INTL"); a.pref = hasSubTag(i, "PREF"); a.pobox = subTagText(i, "POBOX"); a.extaddr = subTagText(i, "EXTADR"); a.street = subTagText(i, "STREET"); a.locality = subTagText(i, "LOCALITY"); a.region = subTagText(i, "REGION"); a.pcode = subTagText(i, "PCODE"); a.country = subTagText(i, "CTRY"); if ( a.country.isEmpty() ) // FIXME: Workaround for Psi prior to 0.9 if ( hasSubTag(i, "COUNTRY") ) a.country = subTagText(i, "COUNTRY"); if ( a.extaddr.isEmpty() ) // FIXME: Workaround for Psi prior to 0.9 if ( hasSubTag(i, "EXTADD") ) a.extaddr = subTagText(i, "EXTADD"); d->addressList.append ( a ); } else if ( tag == "LABEL" ) { Label l; l.home = hasSubTag(i, "HOME"); l.work = hasSubTag(i, "WORK"); l.postal = hasSubTag(i, "POSTAL"); l.parcel = hasSubTag(i, "PARCEL"); l.dom = hasSubTag(i, "DOM"); l.intl = hasSubTag(i, "INTL"); l.pref = hasSubTag(i, "PREF"); QDomNode nn = i.firstChild(); for ( ; !nn.isNull(); nn = nn.nextSibling() ) { QDomElement ii = nn.toElement(); if ( ii.isNull() ) continue; if ( ii.tagName().toUpper() == "LINE" ) l.lines.append ( ii.text().trimmed() ); } d->labelList.append ( l ); } else if ( tag == "TEL" ) { Phone p; p.home = hasSubTag(i, "HOME"); p.work = hasSubTag(i, "WORK"); p.voice = hasSubTag(i, "VOICE"); p.fax = hasSubTag(i, "FAX"); p.pager = hasSubTag(i, "PAGER"); p.msg = hasSubTag(i, "MSG"); p.cell = hasSubTag(i, "CELL"); p.video = hasSubTag(i, "VIDEO"); p.bbs = hasSubTag(i, "BBS"); p.modem = hasSubTag(i, "MODEM"); p.isdn = hasSubTag(i, "ISDN"); p.pcs = hasSubTag(i, "PCS"); p.pref = hasSubTag(i, "PREF"); p.number = subTagText(i, "NUMBER"); if ( p.number.isEmpty() ) // FIXME: Workaround for Psi prior to 0.9 if ( hasSubTag(i, "VOICE") ) p.number = subTagText(i, "VOICE"); d->phoneList.append ( p ); } else if ( tag == "EMAIL" ) { Email m; m.home = hasSubTag(i, "HOME"); m.work = hasSubTag(i, "WORK"); m.internet = hasSubTag(i, "INTERNET"); m.x400 = hasSubTag(i, "X400"); m.userid = subTagText(i, "USERID"); if ( m.userid.isEmpty() ) // FIXME: Workaround for Psi prior to 0.9 if ( !i.text().isEmpty() ) m.userid = i.text().trimmed(); d->emailList.append ( m ); } else if ( tag == "JABBERID" ) d->jid = i.text().trimmed(); else if ( tag == "MAILER" ) d->mailer = i.text().trimmed(); else if ( tag == "TZ" ) d->timezone = i.text().trimmed(); else if ( tag == "GEO" ) { d->geo.lat = subTagText(i, "LAT"); d->geo.lon = subTagText(i, "LON"); } else if ( tag == "TITLE" ) d->title = i.text().trimmed(); else if ( tag == "ROLE" ) d->role = i.text().trimmed(); else if ( tag == "LOGO" ) { d->logo = QCA::Base64().stringToArray( subTagText(i, "BINVAL").replace("\n","") ).toByteArray(); d->logoURI = subTagText(i, "EXTVAL"); } else if ( tag == "AGENT" ) { e = findSubTag(i, "VCARD", &found); if ( found ) { VCard a; if ( a.fromXml(e) ) { if ( !d->agent ) d->agent = new VCard; *(d->agent) = a; } } d->agentURI = subTagText(i, "EXTVAL"); } else if ( tag == "ORG" ) { d->org.name = subTagText(i, "ORGNAME"); QDomNode nn = i.firstChild(); for ( ; !nn.isNull(); nn = nn.nextSibling() ) { QDomElement ii = nn.toElement(); if ( ii.isNull() ) continue; if ( ii.tagName().toUpper() == "ORGUNIT" ) d->org.unit.append( ii.text().trimmed() ); } } else if ( tag == "CATEGORIES") { QDomNode nn = i.firstChild(); for ( ; !nn.isNull(); nn = nn.nextSibling() ) { QDomElement ee = nn.toElement(); if ( ee.isNull() ) continue; if ( ee.tagName().toUpper() == "KEYWORD" ) d->categories << ee.text().trimmed(); } } else if ( tag == "NOTE" ) d->note = i.text().trimmed(); else if ( tag == "PRODID" ) d->prodId = i.text().trimmed(); else if ( tag == "REV" ) d->rev = i.text().trimmed(); else if ( tag == "SORT-STRING" ) d->sortString = i.text().trimmed(); else if ( tag == "SOUND" ) { d->sound = QCA::Base64().stringToArray( subTagText(i, "BINVAL").replace("\n","") ).toByteArray(); d->soundURI = subTagText(i, "EXTVAL"); d->soundPhonetic = subTagText(i, "PHONETIC"); } else if ( tag == "UID" ) d->uid = i.text().trimmed(); else if ( tag == "URL") d->url = i.text().trimmed(); else if ( tag == "DESC" ) d->desc = i.text().trimmed(); else if ( tag == "CLASS" ) { if ( hasSubTag(i, "PUBLIC") ) d->privacyClass = pcPublic; else if ( hasSubTag(i, "PRIVATE") ) d->privacyClass = pcPrivate; else if ( hasSubTag(i, "CONFIDENTIAL") ) d->privacyClass = pcConfidential; } else if ( tag == "KEY" ) { // TODO: Justin, please check out this code e = findSubTag(i, "TYPE", &found); QString type = "text/plain"; if ( found ) type = e.text().trimmed(); e = findSubTag(i, "CRED", &found ); if ( !found ) e = findSubTag(i, "BINVAL", &found); // case for very clever clients ;-) if ( found ) d->key = e.text().toUtf8(); // FIXME } #ifdef YAPSI else if ( tag == "GENDER" ) { QString gender = i.text().trimmed().toLower(); if ( gender == "m" ) d->gender = Male; else if ( gender == "f" ) d->gender = Female; else d->gender = UnknownGender; } else if ( tag == "MOOD" ) { d->mood = i.text().trimmed(); } #endif } return true; }
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; }