gloox 1.0
|
00001 /* 00002 Copyright (c) 2006-2009 by Jakob Schroeter <js@camaya.net> 00003 This file is part of the gloox library. http://camaya.net/gloox 00004 00005 This software is distributed under a license. The full license 00006 agreement can be found in the file LICENSE in this distribution. 00007 This software may not be copied, modified, sold or distributed 00008 other than expressed in the named license agreement. 00009 00010 This software is distributed without any warranty. 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 }