gloox 1.0.27
vcard.cpp
1/*
2 Copyright (c) 2006-2023 by Jakob Schröter <js@camaya.net>
3 This file is part of the gloox library. http://camaya.net/gloox
4
5 This software is distributed under a license. The full license
6 agreement can be found in the file LICENSE in this distribution.
7 This software may not be copied, modified, sold or distributed
8 other than expressed in the named license agreement.
9
10 This software is distributed without any warranty.
11*/
12
13
14#include "vcard.h"
15#include "tag.h"
16#include "base64.h"
17
18namespace gloox
19{
20
21 void VCard::insertField( Tag* vcard, const char* field, const std::string& var )
22 {
23 if( field && !var.empty() )
24 new Tag( vcard, field, var );
25 }
26
27 void VCard::insertField( Tag* vcard, const char* field, bool var )
28 {
29 if( field && var )
30 new Tag( vcard, field );
31 }
32
33 void VCard::checkField( const Tag* vcard, const char* field, std::string& var )
34 {
35 if( field )
36 {
37 Tag* child = vcard->findChild( field );
38 if( child )
39 var = child->cdata();
40 }
41 }
42
44 : StanzaExtension( ExtVCard ), m_class( ClassNone ), m_prodid( "gloox" + GLOOX_VERSION ),
45 m_N( false ), m_PHOTO( false ), m_LOGO( false )
46 {
47 m_valid = true;
48 }
49
50 VCard::VCard( const Tag* vcard )
51 : StanzaExtension( ExtVCard ), m_class( ClassNone ), m_prodid( "gloox" + GLOOX_VERSION ),
52 m_N( false ), m_PHOTO( false ), m_LOGO( false )
53 {
54 if( !vcard || vcard->name() != "vCard" || vcard->xmlns() != XMLNS_VCARD_TEMP )
55 return;
56
57 m_valid = true;
58
59 checkField( vcard, "FN", m_formattedname );
60 checkField( vcard, "NICKNAME", m_nickname );
61 checkField( vcard, "URL", m_url );
62 checkField( vcard, "BDAY", m_bday );
63 checkField( vcard, "JABBERID", m_jabberid );
64 checkField( vcard, "TITLE", m_title );
65 checkField( vcard, "ROLE", m_role );
66 checkField( vcard, "NOTE", m_note );
67 checkField( vcard, "DESC", m_desc );
68 checkField( vcard, "MAILER", m_mailer );
69 checkField( vcard, "TZ", m_tz );
70 checkField( vcard, "PRODID", m_prodid );
71 checkField( vcard, "REV", m_rev );
72 checkField( vcard, "SORT-STRING", m_sortstring );
73 checkField( vcard, "UID", m_uid );
74
75 TagList::const_iterator it = vcard->children().begin();
76 for( ; it != vcard->children().end(); ++it )
77 {
78 const Tag& tag = *(*it);
79 if( tag.name() == "N" )
80 {
81 m_N = true;
82 const Tag * child = tag.findChild( "FAMILY" );
83 if( child )
84 m_name.family = child->cdata();
85 if( ( child = tag.findChild( "GIVEN" ) ) )
86 m_name.given = child->cdata();
87 if( ( child = tag.findChild( "MIDDLE" ) ) )
88 m_name.middle = child->cdata();
89 if( ( child = tag.findChild( "PREFIX" ) ) )
90 m_name.prefix = child->cdata();
91 if( ( child = tag.findChild( "SUFFIX" ) ) )
92 m_name.suffix = child->cdata();
93 }
94 else if( tag.name() == "PHOTO" )
95 {
96 if( tag.hasChild( "EXTVAL" ) )
97 {
98 m_photo.extval = tag.findChild( "EXTVAL" )->cdata();
99 m_PHOTO = true;
100 }
101 else if( tag.hasChild( "TYPE" ) && tag.hasChild( "BINVAL" ) )
102 {
103 std::string binval = tag.findChild( "BINVAL" )->cdata();
104 std::string::size_type pos = 0;
105 while( ( pos = binval.find( '\n' ) ) != std::string::npos )
106 binval.erase( pos, 1 );
107 while( ( pos = binval.find( '\r' ) ) != std::string::npos )
108 binval.erase( pos, 1 );
109 m_photo.type = tag.findChild( "TYPE" )->cdata();
110 m_photo.binval = Base64::decode64( binval );
111 m_PHOTO = true;
112 }
113 }
114 else if( tag.name() == "LOGO" )
115 {
116 if( tag.hasChild( "EXTVAL" ) )
117 {
118 m_logo.extval = tag.findChild( "EXTVAL" )->cdata();
119 m_LOGO = true;
120 }
121 else if( tag.hasChild( "TYPE" ) && tag.hasChild( "BINVAL" ) )
122 {
123 std::string binval = tag.findChild( "BINVAL" )->cdata();
124 std::string::size_type pos = 0;
125 while( ( pos = binval.find( '\n' ) ) != std::string::npos )
126 binval.erase( pos, 1 );
127 while( ( pos = binval.find( '\r' ) ) != std::string::npos )
128 binval.erase( pos, 1 );
129 m_logo.type = tag.findChild( "TYPE" )->cdata();
130 m_logo.binval = Base64::decode64( binval );
131 m_LOGO = true;
132 }
133 }
134 else if( tag.name() == "EMAIL" && tag.hasChild( "USERID" ) )
135 {
136 Email item;
137 item.userid = tag.findChild( "USERID" )->cdata();
138 item.internet = tag.hasChild( "INTERNET" );
139 item.x400 = tag.hasChild( "X400" );
140 item.work = tag.hasChild( "WORK" );
141 item.home = tag.hasChild( "HOME" );
142 item.pref = tag.hasChild( "PREF" );
143 m_emailList.push_back( item );
144 }
145 else if( tag.name() == "ADR" )
146 {
147 Address item;
148 checkField( &tag, "POBOX", item.pobox );
149 checkField( &tag, "EXTADD", item.extadd );
150 checkField( &tag, "STREET", item.street );
151 checkField( &tag, "LOCALITY", item.locality );
152 checkField( &tag, "REGION", item.region );
153 checkField( &tag, "PCODE", item.pcode );
154 checkField( &tag, "CTRY", item.ctry );
155 item.postal = tag.hasChild( "POSTAL" );
156 item.parcel = tag.hasChild( "PARCEL" );
157 item.work = tag.hasChild( "WORK" );
158 item.home = tag.hasChild( "HOME" );
159 item.pref = tag.hasChild( "PREF" );
160 item.dom = tag.hasChild( "DOM" );
161 item.intl = !item.dom && tag.hasChild( "INTL" );
162 m_addressList.push_back( item );
163 }
164 else if( tag.name() == "LABEL" )
165 {
166 Label item;
167 TagList::const_iterator it2 = tag.children().begin();
168 for( ; it2 != tag.children().end(); ++it2 )
169 {
170 if( (*it2)->name() == "LINE" )
171 item.lines.push_back( (*it)->cdata() );
172 item.postal = (*it2)->name() == "POSTAL";
173 item.parcel = (*it2)->name() == "PARCEL";
174 item.work = (*it2)->name() == "WORK";
175 item.home = (*it2)->name() == "HOME";
176 item.pref = (*it2)->name() == "PREF";
177 item.dom = (*it2)->name() == "DOM";
178 item.intl = !item.dom && (*it2)->name() == "INTL";
179 }
180 m_labelList.push_back( item );
181 }
182 else if( tag.name() == "TEL" && tag.hasChild( "NUMBER" ) )
183 {
184 Telephone item;
185 item.number = tag.findChild( "NUMBER" )->cdata();
186 item.work = tag.hasChild( "WORK" );
187 item.home = tag.hasChild( "HOME" );
188 item.voice = tag.hasChild( "VOICE" );
189 item.fax = tag.hasChild( "FAX" );
190 item.pager = tag.hasChild( "PAGER" );
191 item.msg = tag.hasChild( "MSG" );
192 item.cell = tag.hasChild( "CELL" );
193 item.video = tag.hasChild( "VIDEO" );
194 item.bbs = tag.hasChild( "BBS" );
195 item.modem = tag.hasChild( "MODEM" );
196 item.isdn = tag.hasChild( "ISDN" );
197 item.pcs = tag.hasChild( "PCS" );
198 item.pref = tag.hasChild( "PREF" );
199 m_telephoneList.push_back( item );
200 }
201 else if( tag.name() == "ORG" )
202 {
203 TagList::const_iterator ito = tag.children().begin();
204 for( ; ito != tag.children().end(); ++ito )
205 {
206 if( (*ito)->name() == "ORGNAME" )
207 m_org.name = (*ito)->cdata();
208 else if( (*ito)->name() == "ORGUNIT" )
209 m_org.units.push_back( (*ito)->cdata() );
210 }
211 }
212 else if( tag.name() == "GEO" )
213 {
214 checkField( &tag, "LON", m_geo.longitude );
215 checkField( &tag, "LAT", m_geo.latitude );
216 }
217 else if( tag.name() == "CLASS" )
218 {
219 if( tag.hasChild( "PRIVATE" ) )
220 m_class = ClassPrivate;
221 else if( tag.hasChild( "PUBLIC" ) )
222 m_class = ClassPublic;
223 else if( tag.hasChild( "CONFIDENTIAL" ) )
224 m_class = ClassConfidential;
225 }
226
227 }
228
229 }
230
231 void VCard::setName( const std::string& family, const std::string& given,
232 const std::string& middle, const std::string& prefix,
233 const std::string& suffix )
234 {
235 m_name.family = family;
236 m_name.given = given;
237 m_name.middle = middle;
238 m_name.prefix = prefix;
239 m_name.suffix = suffix;
240 m_N = true;
241 }
242
243 void VCard::setPhotoUri( const std::string& extval )
244 {
245 if( !extval.empty() )
246 {
247 m_photo.extval= extval;
248 m_PHOTO = true;
249 }
250 }
251
252 void VCard::setPhoto( const std::string& type, const std::string& binval )
253 {
254 if( !type.empty() && !binval.empty() )
255 {
256 m_photo.type = type;
257 m_photo.binval = binval;
258 m_PHOTO = true;
259 }
260 else
261 {
262 m_photo.type = EmptyString;
263 m_photo.binval = EmptyString;
264 m_photo.extval = EmptyString;
265 m_PHOTO = false;
266 }
267 }
268
269 void VCard::setLogo( const std::string& extval )
270 {
271 if( !extval.empty() )
272 {
273 m_logo.extval = extval;
274 m_LOGO = true;
275 }
276 }
277
278 void VCard::setLogo( const std::string& type, const std::string& binval )
279 {
280 if( !type.empty() && !binval.empty() )
281 {
282 m_logo.type = type;
283 m_logo.binval = binval;
284 m_LOGO = true;
285 }
286 else
287 {
288 m_logo.type = EmptyString;
289 m_logo.binval = EmptyString;
290 m_logo.extval = EmptyString;
291 m_LOGO = false;
292 }
293 }
294
295 void VCard::addEmail( const std::string& userid, int type )
296 {
297 if( userid.empty() )
298 return;
299
300 Email item;
301 item.userid = userid;
302 item.internet = ((type & AddrTypeInet) == AddrTypeInet);
303 item.x400 = ((type & AddrTypeX400) == AddrTypeX400);
304 item.work = ((type & AddrTypeWork) == AddrTypeWork);
305 item.home = ((type & AddrTypeHome) == AddrTypeHome);
306 item.pref = ((type & AddrTypePref) == AddrTypePref);
307
308 m_emailList.push_back( item );
309 }
310
311 void VCard::addAddress( const std::string& pobox, const std::string& extadd,
312 const std::string& street, const std::string& locality,
313 const std::string& region, const std::string& pcode,
314 const std::string& ctry, int type )
315 {
316 if( pobox.empty() && extadd.empty() && street.empty() &&
317 locality.empty() && region.empty() && pcode.empty() && ctry.empty() )
318 return;
319
320 Address item;
321 item.pobox = pobox;
322 item.extadd = extadd;
323 item.street = street;
324 item.locality = locality;
325 item.region = region;
326 item.pcode = pcode;
327 item.ctry = ctry;
328 item.home = ((type & AddrTypeHome) == AddrTypeHome);
329 item.work = ((type & AddrTypeWork) == AddrTypeWork);
330 item.parcel = ((type & AddrTypeParcel) == AddrTypeParcel);
331 item.postal = ((type & AddrTypePostal) == AddrTypePostal);
332 item.dom = ((type & AddrTypeDom) == AddrTypeDom);
333 item.intl = !item.dom && ((type & AddrTypeIntl) == AddrTypeIntl);
334 item.pref = ((type & AddrTypePref) == AddrTypePref);
335
336 m_addressList.push_back( item );
337 }
338
339 void VCard::addLabel( const StringList& lines, int type )
340 {
341 if( lines.empty() )
342 return;
343
344 Label item;
345 item.lines = lines;
346 item.work = ((type & AddrTypeWork) == AddrTypeWork);
347 item.home = ((type & AddrTypeHome) == AddrTypeHome);
348 item.postal = ((type & AddrTypePostal) == AddrTypePostal);
349 item.parcel = ((type & AddrTypeParcel) == AddrTypeParcel);
350 item.pref = ((type & AddrTypePref) == AddrTypePref);
351 item.dom = ((type & AddrTypeDom) == AddrTypeDom);
352 item.intl = !item.dom && ((type & AddrTypeIntl) == AddrTypeIntl);
353
354 m_labelList.push_back( item );
355 }
356
357 void VCard::addTelephone( const std::string& number, int type )
358 {
359 if( number.empty() )
360 return;
361
362 Telephone item;
363 item.number = number;
364 item.work = ((type & AddrTypeWork) == AddrTypeWork);
365 item.home = ((type & AddrTypeHome) == AddrTypeHome);
366 item.voice = ((type & AddrTypeVoice) == AddrTypeVoice);
367 item.fax = ((type & AddrTypeFax) == AddrTypeFax);
368 item.pager = ((type & AddrTypePager) == AddrTypePager);
369 item.msg = ((type & AddrTypeMsg) == AddrTypeMsg);
370 item.cell = ((type & AddrTypeCell) == AddrTypeCell);
371 item.video = ((type & AddrTypeVideo) == AddrTypeVideo);
372 item.bbs = ((type & AddrTypeBbs) == AddrTypeBbs);
373 item.modem = ((type & AddrTypeModem) == AddrTypeModem);
374 item.isdn = ((type & AddrTypeIsdn) == AddrTypeIsdn);
375 item.pcs = ((type & AddrTypePcs) == AddrTypePcs);
376 item.pref = ((type & AddrTypePref) == AddrTypePref);
377
378 m_telephoneList.push_back( item );
379 }
380
381 void VCard::setGeo( const std::string& lat, const std::string& lon )
382 {
383 if( !lat.empty() && !lon.empty() )
384 {
385 m_geo.latitude = lat;
386 m_geo.longitude = lon;
387 }
388 }
389
390 void VCard::setOrganization( const std::string& orgname, const StringList& orgunits )
391 {
392 if( !orgname.empty() )
393 {
394 m_org.name = orgname;
395 m_org.units = orgunits;
396 }
397 }
398
399 const std::string& VCard::filterString() const
400 {
401 static const std::string filter = "/iq/vCard[@xmlns='" + XMLNS_VCARD_TEMP + "']";
402 return filter;
403 }
404
406 {
407 Tag* v = new Tag( "vCard" );
409
410 if( !m_valid )
411 return v;
412
413 v->addAttribute( "version", "3.0" );
414
415 insertField( v, "FN", m_formattedname );
416 insertField( v, "NICKNAME", m_nickname );
417 insertField( v, "URL", m_url );
418 insertField( v, "BDAY", m_bday );
419 insertField( v, "JABBERID", m_jabberid );
420 insertField( v, "TITLE", m_title );
421 insertField( v, "ROLE", m_role );
422 insertField( v, "NOTE", m_note );
423 insertField( v, "DESC", m_desc );
424 insertField( v, "MAILER", m_mailer );
425 insertField( v, "TZ", m_tz );
426 insertField( v, "REV", m_rev );
427 insertField( v, "SORT_STRING", m_sortstring );
428 insertField( v, "UID", m_uid );
429
430 if( m_N )
431 {
432 Tag* n = new Tag( v, "N" );
433 insertField( n, "FAMILY", m_name.family );
434 insertField( n, "GIVEN", m_name.given );
435 insertField( n, "MIDDLE", m_name.middle );
436 insertField( n, "PREFIX", m_name.prefix );
437 insertField( n, "SUFFIX", m_name.suffix );
438 }
439
440 if( m_PHOTO )
441 {
442 Tag* p = new Tag( v, "PHOTO" );
443 if( !m_photo.extval.empty() )
444 {
445 new Tag( p, "EXTVAL", m_photo.extval );
446 }
447 else if( !m_photo.type.empty() && !m_photo.binval.empty() )
448 {
449 new Tag( p, "TYPE", m_photo.type );
450 new Tag( p, "BINVAL", Base64::encode64( m_photo.binval ) );
451 }
452 }
453
454 if( m_LOGO )
455 {
456 Tag* l = new Tag( v, "LOGO" );
457 if( !m_logo.extval.empty() )
458 {
459 new Tag( l, "EXTVAL", m_logo.extval );
460 }
461 else if( !m_logo.type.empty() && !m_logo.binval.empty() )
462 {
463 new Tag( l, "TYPE", m_logo.type );
464 new Tag( l, "BINVAL", Base64::encode64( m_logo.binval ) );
465 }
466 }
467
468 EmailList::const_iterator ite = m_emailList.begin();
469 for( ; ite != m_emailList.end(); ++ite )
470 {
471 Tag* e = new Tag( v, "EMAIL" );
472 insertField( e, "INTERNET", (*ite).internet );
473 insertField( e, "WORK", (*ite).work );
474 insertField( e, "HOME", (*ite).home );
475 insertField( e, "X400", (*ite).x400 );
476 insertField( e, "PREF", (*ite).pref );
477 insertField( e, "USERID", (*ite).userid );
478 }
479
480 AddressList::const_iterator ita = m_addressList.begin();
481 for( ; ita != m_addressList.end(); ++ita )
482 {
483 Tag* a = new Tag( v, "ADR" );
484 insertField( a, "POSTAL", (*ita).postal );
485 insertField( a, "PARCEL", (*ita).parcel );
486 insertField( a, "HOME", (*ita).home );
487 insertField( a, "WORK", (*ita).work );
488 insertField( a, "PREF", (*ita).pref );
489 insertField( a, "DOM", (*ita).dom );
490 if( !(*ita).dom )
491 insertField( a, "INTL", (*ita).intl );
492
493 insertField( a, "POBOX", (*ita).pobox );
494 insertField( a, "EXTADD", (*ita).extadd );
495 insertField( a, "STREET", (*ita).street );
496 insertField( a, "LOCALITY", (*ita).locality );
497 insertField( a, "REGION", (*ita).region );
498 insertField( a, "PCODE", (*ita).pcode );
499 insertField( a, "CTRY", (*ita).ctry );
500 }
501
502 TelephoneList::const_iterator itt = m_telephoneList.begin();
503 for( ; itt != m_telephoneList.end(); ++itt )
504 {
505 Tag* t = new Tag( v, "TEL" );
506 insertField( t, "NUMBER", (*itt).number );
507 insertField( t, "HOME", (*itt).home );
508 insertField( t, "WORK", (*itt).work );
509 insertField( t, "VOICE", (*itt).voice );
510 insertField( t, "FAX", (*itt).fax );
511 insertField( t, "PAGER", (*itt).pager );
512 insertField( t, "MSG", (*itt).msg );
513 insertField( t, "CELL", (*itt).cell );
514 insertField( t, "VIDEO", (*itt).video );
515 insertField( t, "BBS", (*itt).bbs );
516 insertField( t, "MODEM", (*itt).modem );
517 insertField( t, "ISDN", (*itt).isdn );
518 insertField( t, "PCS", (*itt).pcs );
519 insertField( t, "PREF", (*itt).pref );
520 }
521
522 if( !m_geo.latitude.empty() && !m_geo.longitude.empty() )
523 {
524 Tag* g = new Tag( v, "GEO" );
525 new Tag( g, "LAT", m_geo.latitude );
526 new Tag( g, "LON", m_geo.longitude );
527 }
528
529 if( !m_org.name.empty() )
530 {
531 Tag* o = new Tag( v, "ORG" );
532 new Tag( o, "ORGNAME", m_org.name );
533 StringList::const_iterator ito = m_org.units.begin();
534 for( ; ito != m_org.units.end(); ++ito )
535 new Tag( o, "ORGUNIT", (*ito) );
536 }
537
538 if( m_class != ClassNone )
539 {
540 Tag* c = new Tag( v, "CLASS" );
541 switch( m_class )
542 {
543 case ClassPublic:
544 new Tag( c, "PUBLIC" );
545 break;
546 case ClassPrivate:
547 new Tag( c, "PRIVATE" );
548 break;
550 new Tag( c, "CONFIDENTIAL" );
551 break;
552 default:
553 break;
554 }
555 }
556
557 return v;
558 }
559}
This class abstracts a stanza extension, which is usually an XML child element in a specific namespac...
This is an abstraction of an XML element.
Definition tag.h:47
Tag * findChild(const std::string &name) const
Definition tag.cpp:624
const std::string & name() const
Definition tag.h:394
const std::string xmlns() const
Definition tag.cpp:543
bool addAttribute(Attribute *attr)
Definition tag.cpp:354
bool hasChild(const std::string &name, const std::string &attr=EmptyString, const std::string &value=EmptyString) const
Definition tag.cpp:615
const std::string cdata() const
Definition tag.cpp:497
const TagList & children() const
Definition tag.cpp:510
bool setXmlns(const std::string &xmlns, const std::string &prefix=EmptyString)
Definition tag.cpp:522
void setLogo(const std::string &extval)
Definition vcard.cpp:269
void addEmail(const std::string &userid, int type)
Definition vcard.cpp:295
void setName(const std::string &family, const std::string &given, const std::string &middle=EmptyString, const std::string &prefix=EmptyString, const std::string &suffix=EmptyString)
Definition vcard.cpp:231
@ ClassNone
Definition vcard.h:85
@ ClassPrivate
Definition vcard.h:87
@ ClassPublic
Definition vcard.h:86
@ ClassConfidential
Definition vcard.h:88
void setPhotoUri(const std::string &extval)
Definition vcard.cpp:243
void addLabel(const StringList &lines, int type)
Definition vcard.cpp:339
void setGeo(const std::string &lat, const std::string &lon)
Definition vcard.cpp:381
virtual const std::string & filterString() const
Definition vcard.cpp:399
void addAddress(const std::string &pobox, const std::string &extadd, const std::string &street, const std::string &locality, const std::string &region, const std::string &pcode, const std::string &ctry, int type)
Definition vcard.cpp:311
@ AddrTypeMsg
Definition vcard.h:59
@ AddrTypeX400
Definition vcard.h:50
@ AddrTypePref
Definition vcard.h:49
@ AddrTypeModem
Definition vcard.h:63
@ AddrTypeWork
Definition vcard.h:48
@ AddrTypeDom
Definition vcard.h:54
@ AddrTypeInet
Definition vcard.h:51
@ AddrTypeParcel
Definition vcard.h:52
@ AddrTypeVideo
Definition vcard.h:61
@ AddrTypeIsdn
Definition vcard.h:64
@ AddrTypeHome
Definition vcard.h:47
@ AddrTypeBbs
Definition vcard.h:62
@ AddrTypeIntl
Definition vcard.h:55
@ AddrTypeFax
Definition vcard.h:57
@ AddrTypePcs
Definition vcard.h:65
@ AddrTypeVoice
Definition vcard.h:56
@ AddrTypePager
Definition vcard.h:58
@ AddrTypePostal
Definition vcard.h:53
@ AddrTypeCell
Definition vcard.h:60
void setOrganization(const std::string &orgname, const StringList &orgunits)
Definition vcard.cpp:390
void addTelephone(const std::string &number, int type)
Definition vcard.cpp:357
void setPhoto(const std::string &type=EmptyString, const std::string &binval=EmptyString)
Definition vcard.cpp:252
virtual Tag * tag() const
Definition vcard.cpp:405
const std::string decode64(const std::string &input)
Definition base64.cpp:83
const std::string encode64(const std::string &input)
Definition base64.cpp:38
The namespace for the gloox library.
Definition adhoc.cpp:28
const std::string GLOOX_VERSION
Definition gloox.cpp:119
std::list< std::string > StringList
Definition gloox.h:1251
const std::string XMLNS_VCARD_TEMP
Definition gloox.cpp:56
const std::string EmptyString
Definition gloox.cpp:124
std::string ctry
Definition vcard.h:146
std::string region
Definition vcard.h:144
std::string locality
Definition vcard.h:143
std::string extadd
Definition vcard.h:141
std::string street
Definition vcard.h:142
std::string pobox
Definition vcard.h:140
std::string pcode
Definition vcard.h:145
std::string userid
Definition vcard.h:96
std::string latitude
Definition vcard.h:176
std::string longitude
Definition vcard.h:177
StringList lines
Definition vcard.h:161
std::string middle
Definition vcard.h:75
std::string given
Definition vcard.h:74
std::string prefix
Definition vcard.h:76
std::string suffix
Definition vcard.h:77
std::string family
Definition vcard.h:73
std::string name
Definition vcard.h:185
StringList units
Definition vcard.h:186
std::string binval
Definition vcard.h:197
std::string extval
Definition vcard.h:195
std::string type
Definition vcard.h:198
std::string number
Definition vcard.h:114