00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "vcard.h"
00015 #include "tag.h"
00016 #include "base64.h"
00017
00018 namespace gloox
00019 {
00020
00021 VCard::VCard()
00022 : m_class( ClassNone ), m_prodid( "gloox" + GLOOX_VERSION ),
00023 m_N( false ), m_PHOTO( false ), m_LOGO( false )
00024 {
00025 }
00026
00027 VCard::VCard( Tag *vcard )
00028 : m_class( ClassNone ), m_prodid( "gloox" + GLOOX_VERSION ),
00029 m_N( false ), m_PHOTO( false ), m_LOGO( false )
00030 {
00031 checkField( vcard, "FN", m_formattedname );
00032 checkField( vcard, "NICKNAME", m_nickname );
00033 checkField( vcard, "URL", m_url );
00034 checkField( vcard, "BDAY", m_bday );
00035 checkField( vcard, "JABBERID", m_jabberid );
00036 checkField( vcard, "TITLE", m_title );
00037 checkField( vcard, "ROLE", m_role );
00038 checkField( vcard, "NOTE", m_note );
00039 checkField( vcard, "DESC", m_desc );
00040 checkField( vcard, "MAILER", m_mailer );
00041 checkField( vcard, "TZ", m_tz );
00042 checkField( vcard, "PRODID", m_prodid );
00043 checkField( vcard, "REV", m_rev );
00044 checkField( vcard, "SORT-STRING", m_sortstring );
00045 checkField( vcard, "UID", m_uid );
00046
00047 Tag::TagList::const_iterator it = vcard->children().begin();
00048 for( ; it != vcard->children().end(); ++it )
00049 {
00050 if( (*it)->name() == "N" )
00051 {
00052 m_N = true;
00053 if( (*it)->hasChild( "FAMILY" ) )
00054 m_name.family = (*it)->findChild( "FAMILY" )->cdata();
00055 if( (*it)->hasChild( "GIVEN" ) )
00056 m_name.given = (*it)->findChild( "GIVEN" )->cdata();
00057 if( (*it)->hasChild( "MIDDLE" ) )
00058 m_name.middle = (*it)->findChild( "MIDDLE" )->cdata();
00059 if( (*it)->hasChild( "PREFIX" ) )
00060 m_name.prefix = (*it)->findChild( "PREFIX" )->cdata();
00061 if( (*it)->hasChild( "SUFFIX" ) )
00062 m_name.suffix = (*it)->findChild( "SUFFIX" )->cdata();
00063 }
00064 else if( (*it)->name() == "PHOTO" )
00065 {
00066 if( (*it)->hasChild( "EXTVAL" ) )
00067 {
00068 m_photo.extval = (*it)->findChild( "EXTVAL" )->cdata();
00069 m_PHOTO = true;
00070 }
00071 else if( (*it)->hasChild( "TYPE" ) && (*it)->hasChild( "BINVAL" ) )
00072 {
00073 std::string binval = (*it)->findChild( "BINVAL" )->cdata();
00074 std::string::size_type pos = 0;
00075 while( ( pos = binval.find( '\n' ) ) != std::string::npos )
00076 binval.erase( pos, 1 );
00077 m_photo.type = (*it)->findChild( "TYPE" )->cdata();
00078 m_photo.binval = Base64::decode64( binval );
00079 m_PHOTO = true;
00080 }
00081 }
00082 else if( (*it)->name() == "LOGO" )
00083 {
00084 if( (*it)->hasChild( "EXTVAL" ) )
00085 {
00086 m_logo.extval = (*it)->findChild( "EXTVAL" )->cdata();
00087 m_LOGO = true;
00088 }
00089 else if( (*it)->hasChild( "TYPE" ) && (*it)->hasChild( "BINVAL" ) )
00090 {
00091 std::string binval = (*it)->findChild( "BINVAL" )->cdata();
00092 std::string::size_type pos = 0;
00093 while( ( pos = binval.find( '\n' ) ) != std::string::npos )
00094 binval.erase( pos, 1 );
00095 m_logo.type = (*it)->findChild( "TYPE" )->cdata();
00096 m_logo.binval = Base64::decode64( binval );
00097 m_LOGO = true;
00098 }
00099 }
00100 else if( (*it)->name() == "EMAIL" && (*it)->hasChild( "USERID" ) )
00101 {
00102 Email item;
00103 item.userid = (*it)->findChild( "USERID" )->cdata();
00104 item.internet = (*it)->hasChild( "INTERNET" );
00105 item.x400 = (*it)->hasChild( "X400" );
00106 item.work = (*it)->hasChild( "WORK" );
00107 item.home = (*it)->hasChild( "HOME" );
00108 item.pref = (*it)->hasChild( "PREF" );
00109 m_emailList.push_back( item );
00110 }
00111 else if( (*it)->name() == "ADR" )
00112 {
00113 Address item;
00114 checkField( (*it), "POBOX", item.pobox );
00115 checkField( (*it), "EXTADD", item.extadd );
00116 checkField( (*it), "STREET", item.street );
00117 checkField( (*it), "LOCALITY", item.locality );
00118 checkField( (*it), "REGION", item.region );
00119 checkField( (*it), "PCODE", item.pcode );
00120 checkField( (*it), "CTRY", item.ctry );
00121 item.postal = (*it)->hasChild( "POSTAL" );
00122 item.parcel = (*it)->hasChild( "PARCEL" );
00123 item.work = (*it)->hasChild( "WORK" );
00124 item.home = (*it)->hasChild( "HOME" );
00125 item.pref = (*it)->hasChild( "PREF" );
00126 item.dom = (*it)->hasChild( "DOM" );
00127 item.intl = !item.dom && (*it)->hasChild( "INTL" );
00128 m_addressList.push_back( item );
00129 }
00130 else if( (*it)->name() == "LABEL" )
00131 {
00132 Label item;
00133 Tag::TagList::const_iterator it2 = (*it)->children().begin();
00134 for( ; it2 != (*it)->children().end(); ++it2 )
00135 {
00136 if( (*it2)->name() == "LINE" )
00137 item.lines.push_back( (*it)->cdata() );
00138 item.postal = (*it2)->name() == "POSTAL";
00139 item.parcel = (*it2)->name() == "PARCEL";
00140 item.work = (*it2)->name() == "WORK";
00141 item.home = (*it2)->name() == "HOME";
00142 item.pref = (*it2)->name() == "PREF";
00143 item.dom = (*it2)->name() == "DOM";
00144 item.intl = !item.dom && (*it2)->name() == "INTL";
00145 }
00146 m_labelList.push_back( item );
00147 }
00148 else if( (*it)->name() == "TEL" && (*it)->hasChild( "NUMBER" ) )
00149 {
00150 Telephone item;
00151 item.number = (*it)->findChild( "NUMBER" )->cdata();
00152 item.work = (*it)->hasChild( "WORK" );
00153 item.home = (*it)->hasChild( "HOME" );
00154 item.voice = (*it)->hasChild( "VOICE" );
00155 item.fax = (*it)->hasChild( "FAX" );
00156 item.pager = (*it)->hasChild( "PAGER" );
00157 item.msg = (*it)->hasChild( "MSG" );
00158 item.cell = (*it)->hasChild( "CELL" );
00159 item.video = (*it)->hasChild( "VIDEO" );
00160 item.bbs = (*it)->hasChild( "BBS" );
00161 item.modem = (*it)->hasChild( "MODEM" );
00162 item.isdn = (*it)->hasChild( "ISDN" );
00163 item.pcs = (*it)->hasChild( "PCS" );
00164 item.pref = (*it)->hasChild( "PREF" );
00165 m_telephoneList.push_back( item );
00166 }
00167 else if( (*it)->name() == "ORG" )
00168 {
00169 Tag::TagList::const_iterator ito = (*it)->children().begin();
00170 for( ; ito != (*it)->children().end(); ++ito )
00171 {
00172 if( (*ito)->name() == "ORGNAME" )
00173 m_org.name = (*ito)->cdata();
00174 else if( (*ito)->name() == "ORGUNIT" )
00175 m_org.units.push_back( (*ito)->cdata() );
00176 }
00177 }
00178 else if( (*it)->name() == "GEO" )
00179 {
00180 checkField( (*it), "LON", m_geo.longitude );
00181 checkField( (*it), "LAT", m_geo.latitude );
00182 }
00183 else if( (*it)->name() == "CLASS" )
00184 {
00185 if( (*it)->hasChild( "PRIVATE" ) )
00186 m_class = ClassPrivate;
00187 else if( (*it)->hasChild( "PUBLIC" ) )
00188 m_class = ClassPublic;
00189 else if( (*it)->hasChild( "CONFIDENTIAL" ) )
00190 m_class = ClassConfidential;
00191 }
00192
00193 }
00194
00195 }
00196
00197 void VCard::checkField( Tag *vcard, const std::string& field, std::string& var )
00198 {
00199 if( vcard->hasChild( field ) )
00200 var = vcard->findChild( field )->cdata();
00201 }
00202
00203 void VCard::setName( const std::string& family, const std::string& given, const std::string& middle,
00204 const std::string& prefix, const std::string& suffix )
00205 {
00206 m_name.family = family;
00207 m_name.given = given;
00208 m_name.middle = middle;
00209 m_name.prefix = prefix;
00210 m_name.suffix = suffix;
00211 m_N = true;
00212 }
00213
00214 void VCard::setPhoto( const std::string& extval )
00215 {
00216 if( !extval.empty() )
00217 {
00218 m_photo.extval= extval;
00219 m_PHOTO = true;
00220 }
00221 }
00222
00223 void VCard::setPhoto( const std::string& type, const std::string& binval )
00224 {
00225 if( !type.empty() && !binval.empty() )
00226 {
00227 m_photo.type = type;
00228 m_photo.binval = binval;
00229 m_PHOTO = true;
00230 }
00231 }
00232
00233 void VCard::setLogo( const std::string& extval )
00234 {
00235 if( !extval.empty() )
00236 {
00237 m_logo.extval = extval;
00238 m_LOGO = true;
00239 }
00240 }
00241
00242 void VCard::setLogo( const std::string& type, const std::string& binval )
00243 {
00244 if( !type.empty() && !binval.empty() )
00245 {
00246 m_logo.type = type;
00247 m_logo.binval = binval;
00248 m_LOGO = true;
00249 }
00250 }
00251
00252 void VCard::addEmail( const std::string& userid, int type )
00253 {
00254 if( userid.empty() )
00255 return;
00256
00257 Email item;
00258 item.userid = userid;
00259 item.internet = type & AddrTypeInet ? true : false;
00260 item.x400 = type & AddrTypeX400 ? true : false;
00261 item.work = type & AddrTypeWork ? true : false;
00262 item.home = type & AddrTypeHome ? true : false;
00263 item.pref = type & AddrTypePref ? true : false;
00264
00265 m_emailList.push_back( item );
00266 }
00267
00268 void VCard::addAddress( const std::string& pobox, const std::string& extadd,
00269 const std::string& street, const std::string& locality,
00270 const std::string& region, const std::string& pcode,
00271 const std::string& ctry, int type )
00272 {
00273 if( pobox.empty() && extadd.empty() && street.empty() &&
00274 locality.empty() && region.empty() && pcode.empty() && ctry.empty() )
00275 return;
00276
00277 Address item;
00278 item.pobox = pobox;
00279 item.extadd = extadd;
00280 item.street = street;
00281 item.locality = locality;
00282 item.region = region;
00283 item.pcode = pcode;
00284 item.ctry = ctry;
00285 item.home = type & AddrTypeHome ? true : false;
00286 item.work = type & AddrTypeWork ? true : false;
00287 item.parcel = type & AddrTypeParcel ? true : false;
00288 item.postal = type & AddrTypePostal ? true : false;
00289 item.dom = type & AddrTypeDom ? true : false;
00290 item.intl = !item.dom && type & AddrTypeIntl ? true : false;
00291 item.pref = type & AddrTypePref ? true : false;
00292
00293 m_addressList.push_back( item );
00294 }
00295
00296 void VCard::addLabel( const StringList& lines, int type )
00297 {
00298 if( !lines.size() )
00299 return;
00300
00301 Label item;
00302 item.lines = lines;
00303 item.work = type & AddrTypeWork ? true : false;
00304 item.home = type & AddrTypeHome ? true : false;
00305 item.postal = type & AddrTypePostal ? true : false;
00306 item.parcel = type & AddrTypeParcel ? true : false;
00307 item.pref = type & AddrTypePref ? true : false;
00308 item.dom = type & AddrTypeDom ? true : false;
00309 item.intl = !item.dom && type & AddrTypeIntl;
00310
00311 m_labelList.push_back( item );
00312 }
00313
00314 void VCard::addTelephone( const std::string& number, int type )
00315 {
00316 if( number.empty() )
00317 return;
00318
00319 Telephone item;
00320 item.number = number;
00321 item.work = type & AddrTypeWork ? true : false;
00322 item.home = type & AddrTypeHome ? true : false;
00323 item.voice = type & AddrTypeVoice ? true : false;
00324 item.fax = type & AddrTypeFax ? true : false;
00325 item.pager = type & AddrTypePager ? true : false;
00326 item.msg = type & AddrTypeMsg ? true : false;
00327 item.cell = type & AddrTypeCell ? true : false;
00328 item.video = type & AddrTypeVideo ? true : false;
00329 item.bbs = type & AddrTypeBbs ? true : false;
00330 item.modem = type & AddrTypeModem ? true : false;
00331 item.isdn = type & AddrTypeIsdn ? true : false;
00332 item.pcs = type & AddrTypePcs ? true : false;
00333 item.pref = type & AddrTypePref ? true : false;
00334
00335 m_telephoneList.push_back( item );
00336 }
00337
00338 void VCard::setGeo( const std::string& lat, const std::string& lon )
00339 {
00340 if( !lat.empty() && !lon.empty() )
00341 {
00342 m_geo.latitude = lat;
00343 m_geo.longitude = lon;
00344 }
00345 }
00346
00347 void VCard::setOrganization( const std::string& orgname, const StringList& orgunits )
00348 {
00349 if( !orgname.empty() )
00350 {
00351 m_org.name = orgname;
00352 m_org.units = orgunits;
00353 }
00354 }
00355
00356 Tag* VCard::tag() const
00357 {
00358 Tag *v = new Tag( "vCard" );
00359 v->addAttribute( "xmlns", XMLNS_VCARD_TEMP );
00360 v->addAttribute( "version", "3.0" );
00361
00362 insertField( v, "FN", m_formattedname );
00363 insertField( v, "NICKNAME", m_nickname );
00364 insertField( v, "URL", m_url );
00365 insertField( v, "BDAY", m_bday );
00366 insertField( v, "JABBERID", m_jabberid );
00367 insertField( v, "TITLE", m_title );
00368 insertField( v, "ROLE", m_role );
00369 insertField( v, "NOTE", m_note );
00370 insertField( v, "DESC", m_desc );
00371 insertField( v, "MAILER", m_mailer );
00372 insertField( v, "TZ", m_tz );
00373 insertField( v, "REV", m_rev );
00374 insertField( v, "SORT_STRING", m_sortstring );
00375 insertField( v, "UID", m_uid );
00376
00377 if( m_N )
00378 {
00379 Tag *n = new Tag( v, "N" );
00380 insertField( n, "FAMILY", m_name.family );
00381 insertField( n, "GIVEN", m_name.given );
00382 insertField( n, "MIDDLE", m_name.middle );
00383 insertField( n, "PREFIX", m_name.prefix );
00384 insertField( n, "SUFFIX", m_name.suffix );
00385 }
00386
00387 if( m_PHOTO )
00388 {
00389 Tag *p = new Tag( v, "PHOTO" );
00390 if( !m_photo.extval.empty() )
00391 {
00392 new Tag( p, "EXTVAL", m_photo.extval );
00393 }
00394 else if( !m_photo.type.empty() && !m_photo.binval.empty() )
00395 {
00396 new Tag( p, "TYPE", m_photo.type );
00397 new Tag( p, "BINVAL", Base64::encode64( m_photo.binval ) );
00398 }
00399 }
00400
00401 if( m_LOGO )
00402 {
00403 Tag *l = new Tag( v, "LOGO" );
00404 if( !m_logo.extval.empty() )
00405 {
00406 new Tag( l, "EXTVAL", m_logo.extval );
00407 }
00408 else if( !m_logo.type.empty() && !m_logo.binval.empty() )
00409 {
00410 new Tag( l, "TYPE", m_logo.type );
00411 new Tag( l, "BINVAL", Base64::encode64( m_logo.binval ) );
00412 }
00413 }
00414
00415 EmailList::const_iterator ite = m_emailList.begin();
00416 for( ; ite != m_emailList.end(); ++ite )
00417 {
00418 Tag *e = new Tag( v, "EMAIL" );
00419 insertField( e, "INTERNET", (*ite).internet );
00420 insertField( e, "WORK", (*ite).work );
00421 insertField( e, "HOME", (*ite).home );
00422 insertField( e, "X400", (*ite).x400 );
00423 insertField( e, "PREF", (*ite).pref );
00424 insertField( e, "USERID", (*ite).userid );
00425 }
00426
00427 AddressList::const_iterator ita = m_addressList.begin();
00428 for( ; ita != m_addressList.end(); ++ita )
00429 {
00430 Tag *a = new Tag( v, "ADR" );
00431 insertField( a, "POSTAL", (*ita).postal );
00432 insertField( a, "PARCEL", (*ita).parcel );
00433 insertField( a, "HOME", (*ita).home );
00434 insertField( a, "WORK", (*ita).work );
00435 insertField( a, "PREF", (*ita).pref );
00436 insertField( a, "DOM", (*ita).dom );
00437 if( !(*ita).dom )
00438 insertField( a, "INTL", (*ita).intl );
00439
00440 insertField( a, "POBOX", (*ita).pobox );
00441 insertField( a, "EXTADD", (*ita).extadd );
00442 insertField( a, "STREET", (*ita).street );
00443 insertField( a, "LOCALITY", (*ita).locality );
00444 insertField( a, "REGION", (*ita).region );
00445 insertField( a, "PCODE", (*ita).pcode );
00446 insertField( a, "CTRY", (*ita).ctry );
00447 }
00448
00449 TelephoneList::const_iterator itt = m_telephoneList.begin();
00450 for( ; itt != m_telephoneList.end(); ++itt )
00451 {
00452 Tag *t = new Tag( v, "TEL" );
00453 insertField( t, "NUMBER", (*itt).number );
00454 insertField( t, "HOME", (*itt).home );
00455 insertField( t, "WORK", (*itt).work );
00456 insertField( t, "VOICE", (*itt).voice );
00457 insertField( t, "FAX", (*itt).fax );
00458 insertField( t, "PAGER", (*itt).pager );
00459 insertField( t, "MSG", (*itt).msg );
00460 insertField( t, "CELL", (*itt).cell );
00461 insertField( t, "VIDEO", (*itt).video );
00462 insertField( t, "BBS", (*itt).bbs );
00463 insertField( t, "MODEM", (*itt).modem );
00464 insertField( t, "ISDN", (*itt).isdn );
00465 insertField( t, "PCS", (*itt).pcs );
00466 insertField( t, "PREF", (*itt).pref );
00467 }
00468
00469 if( !m_geo.latitude.empty() && !m_geo.longitude.empty() )
00470 {
00471 Tag *g = new Tag( v, "GEO" );
00472 new Tag( g, "LAT", m_geo.latitude );
00473 new Tag( g, "LON", m_geo.longitude );
00474 }
00475
00476 if( !m_org.name.empty() )
00477 {
00478 Tag *o = new Tag( v, "ORG" );
00479 new Tag( o, "ORGNAME", m_org.name );
00480 StringList::const_iterator ito = m_org.units.begin();
00481 for( ; ito != m_org.units.end(); ++ito )
00482 new Tag( o, "ORGUNITS", (*ito) );
00483 }
00484
00485 if( m_class != ClassNone )
00486 {
00487 Tag *c = new Tag( v, "CLASS" );
00488 switch( m_class )
00489 {
00490 case ClassPublic:
00491 new Tag( c, "PUBLIC" );
00492 break;
00493 case ClassPrivate:
00494 new Tag( c, "PRIVATE" );
00495 break;
00496 case ClassConfidential:
00497 new Tag( c, "CONFIDENTIAL" );
00498 break;
00499 default:
00500 break;
00501 }
00502 }
00503
00504 return v;
00505 }
00506
00507 void VCard::insertField( Tag *vcard, const std::string& field, const std::string& var ) const
00508 {
00509 if( !var.empty() )
00510 new Tag( vcard, field, var );
00511 }
00512
00513 void VCard::insertField( Tag *vcard, const std::string& field, bool var ) const
00514 {
00515 if( var )
00516 new Tag( vcard, field );
00517 }
00518
00519 }