diff options
Diffstat (limited to 'kabc/vcard21parser.cpp')
-rw-r--r-- | kabc/vcard21parser.cpp | 608 |
1 files changed, 0 insertions, 608 deletions
diff --git a/kabc/vcard21parser.cpp b/kabc/vcard21parser.cpp deleted file mode 100644 index 8a3bfcaea..000000000 --- a/kabc/vcard21parser.cpp +++ /dev/null @@ -1,608 +0,0 @@ -/* - This file is part of libkabc. - Copyright (c) 2001 Mark Westcott <mark@houseoffish.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <tqmap.h> -#include <tqregexp.h> -#include <kmdcodec.h> - -#include "vcard21parser.h" -#include "vcardconverter.h" - -using namespace KABC; - -bool VCardLineX::isValid() const -{ - // Invalid: if it is "begin:vcard" or "end:vcard" - if ( name == VCARD_BEGIN_N || name == VCARD_END_N ) - return false; - - if ( name[0] == 'x' && name[1] == '-' ) // A custom x- line - return true; - - // This is long but it makes it a bit faster (and saves me from using - // a tree which is probably the ideal situation, but a bit memory heavy) - switch( name[0] ) { - case 'a': - if ( name == VCARD_ADR && qualified && - (qualifiers.contains(VCARD_ADR_DOM) || - qualifiers.contains(VCARD_ADR_INTL) || - qualifiers.contains(VCARD_ADR_POSTAL) || - qualifiers.contains(VCARD_ADR_HOME) || - qualifiers.contains(VCARD_ADR_WORK) || - qualifiers.contains(VCARD_ADR_PREF) - ) ) - return true; - - if ( name == VCARD_AGENT ) - return true; - break; - - case 'b': - if ( name == VCARD_BDAY ) - return true; - break; - - case 'c': - if ( name == VCARD_CATEGORIES ) - return true; - if ( name == VCARD_CLASS && qualified && - (qualifiers.contains(VCARD_CLASS_PUBLIC) || - qualifiers.contains(VCARD_CLASS_PRIVATE) || - qualifiers.contains(VCARD_CLASS_CONFIDENTIAL) - ) ) - return true; - break; - - case 'e': - if ( name == VCARD_EMAIL && qualified && - (qualifiers.contains(VCARD_EMAIL_INTERNET) || - qualifiers.contains(VCARD_EMAIL_PREF) || - qualifiers.contains(VCARD_EMAIL_X400) - ) ) - return true; - break; - - case 'f': - if ( name == VCARD_FN ) - return true; - break; - - case 'g': - if ( name == VCARD_GEO ) - return true; - break; - - case 'k': - if ( name == VCARD_KEY && qualified && - (qualifiers.contains(VCARD_KEY_X509) || - qualifiers.contains(VCARD_KEY_PGP) - ) ) - return true; - break; - - case 'l': - if ( name == VCARD_LABEL ) - return true; - if ( name == VCARD_LOGO ) - return true; - break; - - case 'm': - if ( name == VCARD_MAILER ) - return true; - break; - - case 'n': - if ( name == VCARD_N ) - return true; - if ( name == VCARD_NAME ) - return true; - if ( name == VCARD_NICKNAME ) - return true; - if ( name == VCARD_NOTE ) - return true; - break; - - case 'o': - if ( name == VCARD_ORG ) - return true; - break; - - case 'p': - if ( name == VCARD_PHOTO ) - return true; - if ( name == VCARD_PROFILE ) - return true; - if ( name == VCARD_PRODID ) - return true; - break; - - case 'r': - if ( name == VCARD_ROLE ) - return true; - if ( name == VCARD_REV ) - return true; - break; - - case 's': - if ( name == VCARD_SOURCE ) - return true; - if ( name == VCARD_SOUND ) - return true; - break; - - case 't': - if ( name == VCARD_TEL && qualified && - (qualifiers.contains(VCARD_TEL_HOME) || - qualifiers.contains(VCARD_TEL_WORK) || - qualifiers.contains(VCARD_TEL_PREF) || - qualifiers.contains(VCARD_TEL_VOICE) || - qualifiers.contains(VCARD_TEL_FAX) || - qualifiers.contains(VCARD_TEL_MSG) || - qualifiers.contains(VCARD_TEL_CELL) || - qualifiers.contains(VCARD_TEL_PAGER) || - qualifiers.contains(VCARD_TEL_BBS) || - qualifiers.contains(VCARD_TEL_MODEM) || - qualifiers.contains(VCARD_TEL_CAR) || - qualifiers.contains(VCARD_TEL_ISDN) || - qualifiers.contains(VCARD_TEL_VIDEO) || - qualifiers.contains(VCARD_TEL_PCS) - ) ) - return true; - if ( name == VCARD_TZ ) - return true; - if ( name == VCARD_TITLE ) - return true; - break; - - case 'u': - if ( name == VCARD_URL ) - return true; - if ( name == VCARD_UID ) - return true; - break; - - case 'v': - if ( name == VCARD_VERSION ) - return true; - break; - default: - break; - } - - return false; -} - - -VCard21Parser::VCard21Parser() -{ -} - -VCard21Parser::~VCard21Parser() -{ -} - -void VCard21Parser::readFromString(KABC::AddressBook *addressbook, const TQString &data) -{ - KABC::Addressee mAddressee = readFromString(data); - addressbook->insertAddressee(mAddressee); -} - -KABC::Addressee VCard21Parser::readFromString( const TQString &data) -{ - KABC::Addressee addressee; - VCard21ParserImpl *vCard = VCard21ParserImpl::parseVCard(data); - TQString tmpStr; - - // Check if parsing failed - if (vCard == 0) - { - kdDebug() << "Parsing failed" << endl; - return addressee; - } - //set the addressees name and formated name - TQStringList tmpList = vCard->getValues(VCARD_N); - TQString formattedName = ""; - if (tmpList.count() > 0) - addressee.setFamilyName(tmpList[0]); - if (tmpList.count() > 1) - addressee.setGivenName(tmpList[1]); - if (tmpList.count() > 2) - addressee.setAdditionalName(tmpList[2]); - if (tmpList.count() > 3) - addressee.setPrefix(tmpList[3]); - if (tmpList.count() > 4) - addressee.setSuffix(tmpList[4]); - - tmpStr = (vCard->getValue(VCARD_FN)); - if (!tmpStr.isEmpty()) - addressee.setFormattedName(tmpStr); - - //set the addressee's nick name - tmpStr = vCard->getValue(VCARD_NICKNAME); - addressee.setNickName(tmpStr); - //set the addressee's organization - tmpStr = vCard->getValue(VCARD_ORG); - addressee.setOrganization(tmpStr); - //set the addressee's title - tmpStr = vCard->getValue(VCARD_TITLE); - addressee.setTitle(tmpStr); - //set the addressee's email - we can only deal with two. The preferenced one and one other. - tmpStr = vCard->getValue(VCARD_EMAIL, VCARD_EMAIL_INTERNET); - addressee.insertEmail(tmpStr, false); - tmpStr = vCard->getValue(VCARD_EMAIL,VCARD_EMAIL_PREF); - addressee.insertEmail(tmpStr, true); - //set the addressee's url - tmpStr = vCard->getValue(VCARD_URL); - if (tmpStr.isEmpty()) tmpStr = vCard->getValue(VCARD_URL, VCARD_ADR_WORK); - if (tmpStr.isEmpty()) tmpStr = vCard->getValue(VCARD_URL, VCARD_ADR_HOME); - if (!tmpStr.isEmpty()) { - addressee.setUrl(KURL(tmpStr)); - } - - //set the addressee's birthday - tmpStr = vCard->getValue(VCARD_BDAY); - addressee.setBirthday(VCardStringToDate(tmpStr)); - - //set the addressee's phone numbers - for ( TQValueListIterator<VCardLineX> i = vCard->_vcdata->begin();i != vCard->_vcdata->end(); ++i ) { - if ( (*i).name == VCARD_TEL ) { - int type = 0; - if ( (*i).qualified ) { - if ( (*i).qualifiers.contains( VCARD_TEL_HOME ) ) - type |= PhoneNumber::Home; - if ( (*i).qualifiers.contains( VCARD_TEL_WORK ) ) - type |= PhoneNumber::Work; - if ( (*i).qualifiers.contains( VCARD_TEL_PREF ) ) - type |= PhoneNumber::Pref; - // if ( (*i).qualifiers.contains( VCARD_TEL_VOICE ) ) - // type |= PhoneNumber::Voice; - if ( (*i).qualifiers.contains( VCARD_TEL_FAX ) ) - type |= PhoneNumber::Fax; - if ( (*i).qualifiers.contains( VCARD_TEL_MSG ) ) - type |= PhoneNumber::Msg; - if ( (*i).qualifiers.contains( VCARD_TEL_CELL ) ) - type |= PhoneNumber::Cell; - if ( (*i).qualifiers.contains( VCARD_TEL_PAGER ) ) - type |= PhoneNumber::Pager; - if ( (*i).qualifiers.contains( VCARD_TEL_BBS ) ) - type |= PhoneNumber::Bbs; - if ( (*i).qualifiers.contains( VCARD_TEL_MODEM ) ) - type |= PhoneNumber::Modem; - if ( (*i).qualifiers.contains( VCARD_TEL_CAR ) ) - type |= PhoneNumber::Car; - if ( (*i).qualifiers.contains( VCARD_TEL_ISDN ) ) - type |= PhoneNumber::Isdn; - if ( (*i).qualifiers.contains( VCARD_TEL_VIDEO ) ) - type |= PhoneNumber::Video; - if ( (*i).qualifiers.contains( VCARD_TEL_PCS ) ) - type |= PhoneNumber::Pcs; - } - addressee.insertPhoneNumber( PhoneNumber( (*i).parameters[ 0 ], type ) ); - } - } - - //set the addressee's addresses - for ( TQValueListIterator<VCardLineX> i = vCard->_vcdata->begin();i != vCard->_vcdata->end(); ++i ) { - if ( (*i).name == VCARD_ADR ) { - int type = 0; - if ( (*i).qualified ) { - if ( (*i).qualifiers.contains( VCARD_ADR_DOM ) ) - type |= Address::Dom; - if ( (*i).qualifiers.contains( VCARD_ADR_INTL ) ) - type |= Address::Intl; - if ( (*i).qualifiers.contains( VCARD_ADR_POSTAL ) ) - type |= Address::Postal; - if ( (*i).qualifiers.contains( VCARD_ADR_PARCEL ) ) - type |= Address::Parcel; - if ( (*i).qualifiers.contains( VCARD_ADR_HOME ) ) - type |= Address::Home; - if ( (*i).qualifiers.contains( VCARD_ADR_WORK ) ) - type |= Address::Work; - if ( (*i).qualifiers.contains( VCARD_ADR_PREF ) ) - type |= Address::Pref; - } - addressee.insertAddress( readAddressFromQStringList( (*i).parameters, type ) ); - } - } - - //set the addressee's delivery label - tmpStr = vCard->getValue(VCARD_LABEL); - if (!tmpStr.isEmpty()) { - tmpStr.replace("\r\n","\n"); - Address tmpAddress; - tmpAddress.setLabel(tmpStr); - addressee.insertAddress(tmpAddress); - } - - //set the addressee's notes - tmpStr = vCard->getValue(VCARD_NOTE); - tmpStr.replace("\r\n","\n"); - addressee.setNote(tmpStr); - - //set the addressee's timezone - tmpStr = vCard->getValue(VCARD_TZ); - TimeZone tmpZone(tmpStr.toInt()); - addressee.setTimeZone(tmpZone); - - //set the addressee's geographical position - tmpList = vCard->getValues(VCARD_GEO); - if (tmpList.count()==2) - { - tmpStr = tmpList[0]; - float glat = tmpStr.toFloat(); - tmpStr = tmpList[1]; - float glong = tmpStr.toFloat(); - Geo tmpGeo(glat,glong); - addressee.setGeo(tmpGeo); - } - - //set the last revision date - tmpStr = vCard->getValue(VCARD_REV); - addressee.setRevision(VCardStringToDate(tmpStr)); - - //set the role of the addressee - tmpStr = vCard->getValue(VCARD_ROLE); - addressee.setRole(tmpStr); - - delete vCard; - - return addressee; -} - - - -KABC::Address VCard21Parser::readAddressFromQStringList ( const TQStringList &data, const int type ) -{ - KABC::Address mAddress; - mAddress.setType( type ); - - if ( data.count() > 0 ) - mAddress.setPostOfficeBox( data[0] ); - if ( data.count() > 1 ) - mAddress.setExtended( data[1] ); - if ( data.count() > 2 ) - mAddress.setStreet( data[2] ); - if ( data.count() > 3 ) - mAddress.setLocality( data[3] ); - if ( data.count() > 4 ) - mAddress.setRegion( data[4] ); - if ( data.count() > 5 ) - mAddress.setPostalCode( data[5] ); - if ( data.count() > 6 ) - mAddress.setCountry( data[6] ); - - return mAddress; -} - - -VCard21ParserImpl *VCard21ParserImpl::parseVCard( const TQString& vc, int *err ) -{ - int _err = 0; - int _state = VC_STATE_BEGIN; - - TQValueList<VCardLineX> *vcdata; - TQValueList<TQString> lines; - - vcdata = new TQValueList<VCardLineX>; - - lines = TQStringList::split( TQRegExp( "[\x0d\x0a]" ), vc ); - - // for each line in the vCard - for ( TQStringList::Iterator j = lines.begin(); j != lines.end(); ++j ) { - VCardLineX _vcl; - - // take spaces off the end - ugly but necessary hack - for ( int g = (*j).length()-1; g > 0 && (*j)[g].isSpace(); --g ) - (*j)[g] = 0; - - // first token: - // verify state, update if necessary - if ( _state & VC_STATE_BEGIN) { - if ( !tqstricmp( (*j).latin1(), VCARD_BEGIN ) ) { - _state = VC_STATE_BODY; - continue; - } else { - _err = VC_ERR_NO_BEGIN; - break; - } - } else if ( _state & VC_STATE_BODY ) { - if ( !tqstricmp( (*j).latin1(), VCARD_END ) ) { - _state |= VC_STATE_END; - break; - } - - // split into two tokens - int colon = (*j).find( ':' ); - if ( colon < 0 ) { - _err = VC_ERR_INVALID_LINE; - break; - } - - TQString key = (*j).left( colon ); - TQString value = (*j).mid( colon + 1 ); - - // check for qualifiers and - // set name, qualified, qualifier(s) - TQStringList keyTokens = TQStringList::split( ';', key ); - bool qp = false, first_pass = true; - bool b64 = false; - - if ( keyTokens.count() > 0 ) { - _vcl.qualified = false; - _vcl.name = keyTokens[ 0 ].lower(); - - for ( TQStringList::Iterator z = keyTokens.begin(); z != keyTokens.end(); ++z ) { - TQString zz = (*z).lower(); - if ( zz == VCARD_QUOTED_PRINTABLE || zz == VCARD_ENCODING_QUOTED_PRINTABLE ) { - qp = true; - } else if ( zz == VCARD_BASE64 ) { - b64 = true; - } else if ( !first_pass ) { - _vcl.qualified = true; - _vcl.qualifiers.append( zz ); - } - first_pass = false; - } - } else { - _err = VC_ERR_INVALID_LINE; - } - - if ( _err != 0 ) - break; - - if ( _vcl.name == VCARD_VERSION ) - _state |= VC_STATE_HAVE_VERSION; - - if ( _vcl.name == VCARD_N || _vcl.name == VCARD_FN ) - _state |= VC_STATE_HAVE_N; - - // second token: - // split into tokens by ; - // add to parameters vector - if ( b64 ) { - if ( value[ value.length() - 1 ] != '=' ) - do { - value += *( ++j ); - } while ( (*j)[ (*j).length() - 1 ] != '=' ); - } else { - if ( qp ) { // join any split lines - while ( value[ value.length() - 1 ] == '=' ) { - value.remove( value.length() - 1, 1 ); - value.append(*( ++j )); - } - } - _vcl.parameters = TQStringList::split( ';', value, true ); - if ( qp ) { // decode the quoted printable - for ( TQStringList::Iterator z = _vcl.parameters.begin(); z != _vcl.parameters.end(); ++z ) - *z = KCodecs::quotedPrintableDecode( TQCString((*z).latin1()) ); - } - } - } else { - _err = VC_ERR_INTERNAL; - break; - } - - // validate VCardLineX - if ( !_vcl.isValid() ) { - _err = VC_ERR_INVALID_LINE; - break; - } - - // add to vector - vcdata->append( _vcl ); - } - - // errors to check at the last minute (exit state related) - if ( _err == 0 ) { - if ( !( _state & VC_STATE_END ) ) // we have to have an end!! - _err = VC_ERR_NO_END; - - if ( !( _state & VC_STATE_HAVE_N ) || // we have to have the mandatories! - !( _state & VC_STATE_HAVE_VERSION ) ) - _err = VC_ERR_MISSING_MANDATORY; - } - - // set the error message if we can, and only return an object - // if the vCard was valid. - if ( err ) - *err = _err; - - if ( _err != 0 ) { - delete vcdata; - return 0; - } - - return new VCard21ParserImpl( vcdata ); -} - -VCard21ParserImpl::VCard21ParserImpl() - : _vcdata( 0 ) -{ -} - -VCard21ParserImpl::VCard21ParserImpl(TQValueList<VCardLineX> *_vcd) - : _vcdata(_vcd) -{ -} - -VCard21ParserImpl::~VCard21ParserImpl() -{ - delete _vcdata; - _vcdata = 0; -} - -TQString VCard21ParserImpl::getValue(const TQString& name, const TQString& qualifier) -{ - TQString failed; - const TQString lowname = name.lower(); - const TQString lowqualifier = qualifier.lower(); - - for (TQValueListIterator<VCardLineX> i = _vcdata->begin();i != _vcdata->end();++i) { - if ((*i).name == lowname && (*i).qualified && (*i).qualifiers.contains(lowqualifier)) { - if ((*i).parameters.count() > 0) - return (*i).parameters[0]; - else return failed; - } - } - return failed; -} - - -TQString VCard21ParserImpl::getValue(const TQString& name) -{ - TQString failed; - const TQString lowname = name.lower(); - - for (TQValueListIterator<VCardLineX> i = _vcdata->begin();i != _vcdata->end();++i) { - if ((*i).name == lowname && !(*i).qualified) { - if ((*i).parameters.count() > 0) - return (*i).parameters[0]; - else return failed; - } - } - return failed; -} - - -TQStringList VCard21ParserImpl::getValues(const TQString& name) -{ - const TQString lowname = name.lower(); - for (TQValueListIterator<VCardLineX> i = _vcdata->begin();i != _vcdata->end();++i) { - if ((*i).name == lowname && !(*i).qualified) - return (*i).parameters; - } - // failed. - return TQStringList(); -} - -TQStringList VCard21ParserImpl::getValues(const TQString& name, const TQString& qualifier) -{ - const TQString lowname = name.lower(); - const TQString lowqualifier = qualifier.lower(); - for (TQValueListIterator<VCardLineX> i = _vcdata->begin();i != _vcdata->end();++i) { - if ((*i).name == lowname && (*i).qualified && (*i).qualifiers.contains(lowqualifier)) - return (*i).parameters; - } - // failed. - return TQStringList(); -} - - |