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