QXmppVCardIq.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827
  1. /*
  2. * Copyright (C) 2008-2012 The QXmpp developers
  3. *
  4. * Author:
  5. * Manjeet Dahiya
  6. *
  7. * Source:
  8. * http://code.google.com/p/qxmpp
  9. *
  10. * This file is a part of QXmpp library.
  11. *
  12. * This library is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU Lesser General Public
  14. * License as published by the Free Software Foundation; either
  15. * version 2.1 of the License, or (at your option) any later version.
  16. *
  17. * This library is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  20. * Lesser General Public License for more details.
  21. *
  22. */
  23. #include <QBuffer>
  24. #include <QXmlStreamWriter>
  25. #include "QXmppVCardIq.h"
  26. #include "QXmppUtils.h"
  27. #include "QXmppConstants.h"
  28. static QString getImageType(const QByteArray &contents)
  29. {
  30. if (contents.startsWith("\x89PNG\x0d\x0a\x1a\x0a"))
  31. return "image/png";
  32. else if (contents.startsWith("\x8aMNG"))
  33. return "video/x-mng";
  34. else if (contents.startsWith("GIF8"))
  35. return "image/gif";
  36. else if (contents.startsWith("BM"))
  37. return "image/bmp";
  38. else if (contents.contains("/* XPM */"))
  39. return "image/x-xpm";
  40. else if (contents.contains("<?xml") && contents.contains("<svg"))
  41. return "image/svg+xml";
  42. else if (contents.startsWith("\xFF\xD8\xFF\xE0"))
  43. return "image/jpeg";
  44. return "image/unknown";
  45. }
  46. class QXmppVCardAddressPrivate : public QSharedData
  47. {
  48. public:
  49. QXmppVCardAddressPrivate() : type(QXmppVCardAddress::None) {};
  50. QString country;
  51. QString locality;
  52. QString postcode;
  53. QString region;
  54. QString street;
  55. QXmppVCardAddress::Type type;
  56. };
  57. /// Constructs an empty address.
  58. QXmppVCardAddress::QXmppVCardAddress()
  59. : d(new QXmppVCardAddressPrivate)
  60. {
  61. }
  62. /// Constructs a copy of \a other.
  63. QXmppVCardAddress::QXmppVCardAddress(const QXmppVCardAddress &other)
  64. : d(other.d)
  65. {
  66. }
  67. QXmppVCardAddress::~QXmppVCardAddress()
  68. {
  69. }
  70. /// Assigns \a other to this address.
  71. QXmppVCardAddress& QXmppVCardAddress::operator=(const QXmppVCardAddress &other)
  72. {
  73. d = other.d;
  74. return *this;
  75. }
  76. /// Returns the country.
  77. QString QXmppVCardAddress::country() const
  78. {
  79. return d->country;
  80. }
  81. /// Sets the country.
  82. void QXmppVCardAddress::setCountry(const QString &country)
  83. {
  84. d->country = country;
  85. }
  86. /// Returns the locality.
  87. QString QXmppVCardAddress::locality() const
  88. {
  89. return d->locality;
  90. }
  91. /// Sets the locality.
  92. void QXmppVCardAddress::setLocality(const QString &locality)
  93. {
  94. d->locality = locality;
  95. }
  96. /// Returns the postcode.
  97. QString QXmppVCardAddress::postcode() const
  98. {
  99. return d->postcode;
  100. }
  101. /// Sets the postcode.
  102. void QXmppVCardAddress::setPostcode(const QString &postcode)
  103. {
  104. d->postcode = postcode;
  105. }
  106. /// Returns the region.
  107. QString QXmppVCardAddress::region() const
  108. {
  109. return d->region;
  110. }
  111. /// Sets the region.
  112. void QXmppVCardAddress::setRegion(const QString &region)
  113. {
  114. d->region = region;
  115. }
  116. /// Returns the street address.
  117. QString QXmppVCardAddress::street() const
  118. {
  119. return d->street;
  120. }
  121. /// Sets the street address.
  122. void QXmppVCardAddress::setStreet(const QString &street)
  123. {
  124. d->street = street;
  125. }
  126. /// Returns the address type, which is a combination of TypeFlag.
  127. QXmppVCardAddress::Type QXmppVCardAddress::type() const
  128. {
  129. return d->type;
  130. }
  131. /// Sets the address \a type, which is a combination of TypeFlag.
  132. void QXmppVCardAddress::setType(QXmppVCardAddress::Type type)
  133. {
  134. d->type = type;
  135. }
  136. /// \cond
  137. void QXmppVCardAddress::parse(const QDomElement &element)
  138. {
  139. if (!element.firstChildElement("HOME").isNull())
  140. d->type |= Home;
  141. if (!element.firstChildElement("WORK").isNull())
  142. d->type |= Work;
  143. if (!element.firstChildElement("POSTAL").isNull())
  144. d->type |= Postal;
  145. if (!element.firstChildElement("PREF").isNull())
  146. d->type |= Preferred;
  147. d->country = element.firstChildElement("CTRY").text();
  148. d->locality = element.firstChildElement("LOCALITY").text();
  149. d->postcode = element.firstChildElement("PCODE").text();
  150. d->region = element.firstChildElement("REGION").text();
  151. d->street = element.firstChildElement("STREET").text();
  152. }
  153. void QXmppVCardAddress::toXml(QXmlStreamWriter *writer) const
  154. {
  155. writer->writeStartElement("ADR");
  156. if (d->type & Home)
  157. writer->writeEmptyElement("HOME");
  158. if (d->type & Work)
  159. writer->writeEmptyElement("WORK");
  160. if (d->type & Postal)
  161. writer->writeEmptyElement("POSTAL");
  162. if (d->type & Preferred)
  163. writer->writeEmptyElement("PREF");
  164. if (!d->country.isEmpty())
  165. writer->writeTextElement("CTRY", d->country);
  166. if (!d->locality.isEmpty())
  167. writer->writeTextElement("LOCALITY", d->locality);
  168. if (!d->postcode.isEmpty())
  169. writer->writeTextElement("PCODE", d->postcode);
  170. if (!d->region.isEmpty())
  171. writer->writeTextElement("REGION", d->region);
  172. if (!d->street.isEmpty())
  173. writer->writeTextElement("STREET", d->street);
  174. writer->writeEndElement();
  175. }
  176. /// \endcond
  177. class QXmppVCardEmailPrivate : public QSharedData
  178. {
  179. public:
  180. QXmppVCardEmailPrivate() : type(QXmppVCardEmail::None) {};
  181. QString address;
  182. QXmppVCardEmail::Type type;
  183. };
  184. /// Constructs an empty e-mail address.
  185. QXmppVCardEmail::QXmppVCardEmail()
  186. : d(new QXmppVCardEmailPrivate)
  187. {
  188. }
  189. /// Constructs a copy of \a other.
  190. QXmppVCardEmail::QXmppVCardEmail(const QXmppVCardEmail &other)
  191. : d(other.d)
  192. {
  193. }
  194. QXmppVCardEmail::~QXmppVCardEmail()
  195. {
  196. }
  197. /// Assigns \a other to this e-mail address.
  198. QXmppVCardEmail& QXmppVCardEmail::operator=(const QXmppVCardEmail &other)
  199. {
  200. d = other.d;
  201. return *this;
  202. }
  203. /// Returns the e-mail address.
  204. QString QXmppVCardEmail::address() const
  205. {
  206. return d->address;
  207. }
  208. /// Sets the e-mail \a address.
  209. void QXmppVCardEmail::setAddress(const QString &address)
  210. {
  211. d->address = address;
  212. }
  213. /// Returns the e-mail type, which is a combination of TypeFlag.
  214. QXmppVCardEmail::Type QXmppVCardEmail::type() const
  215. {
  216. return d->type;
  217. }
  218. /// Sets the e-mail \a type, which is a combination of TypeFlag.
  219. void QXmppVCardEmail::setType(QXmppVCardEmail::Type type)
  220. {
  221. d->type = type;
  222. }
  223. /// \cond
  224. void QXmppVCardEmail::parse(const QDomElement &element)
  225. {
  226. if (!element.firstChildElement("HOME").isNull())
  227. d->type |= Home;
  228. if (!element.firstChildElement("WORK").isNull())
  229. d->type |= Work;
  230. if (!element.firstChildElement("INTERNET").isNull())
  231. d->type |= Internet;
  232. if (!element.firstChildElement("PREF").isNull())
  233. d->type |= Preferred;
  234. if (!element.firstChildElement("X400").isNull())
  235. d->type |= X400;
  236. d->address = element.firstChildElement("USERID").text();
  237. }
  238. void QXmppVCardEmail::toXml(QXmlStreamWriter *writer) const
  239. {
  240. writer->writeStartElement("EMAIL");
  241. if (d->type & Home)
  242. writer->writeEmptyElement("HOME");
  243. if (d->type & Work)
  244. writer->writeEmptyElement("WORK");
  245. if (d->type & Internet)
  246. writer->writeEmptyElement("INTERNET");
  247. if (d->type & Preferred)
  248. writer->writeEmptyElement("PREF");
  249. if (d->type & X400)
  250. writer->writeEmptyElement("X400");
  251. writer->writeTextElement("USERID", d->address);
  252. writer->writeEndElement();
  253. }
  254. /// \endcond
  255. class QXmppVCardPhonePrivate : public QSharedData
  256. {
  257. public:
  258. QXmppVCardPhonePrivate() : type(QXmppVCardPhone::None) {};
  259. QString number;
  260. QXmppVCardPhone::Type type;
  261. };
  262. /// Constructs an empty phone number.
  263. QXmppVCardPhone::QXmppVCardPhone()
  264. : d(new QXmppVCardPhonePrivate)
  265. {
  266. }
  267. /// Constructs a copy of \a other.
  268. QXmppVCardPhone::QXmppVCardPhone(const QXmppVCardPhone &other)
  269. : d(other.d)
  270. {
  271. }
  272. QXmppVCardPhone::~QXmppVCardPhone()
  273. {
  274. }
  275. /// Assigns \a other to this phone number.
  276. QXmppVCardPhone& QXmppVCardPhone::operator=(const QXmppVCardPhone &other)
  277. {
  278. d = other.d;
  279. return *this;
  280. }
  281. /// Returns the phone number.
  282. QString QXmppVCardPhone::number() const
  283. {
  284. return d->number;
  285. }
  286. /// Sets the phone \a number.
  287. void QXmppVCardPhone::setNumber(const QString &number)
  288. {
  289. d->number = number;
  290. }
  291. /// Returns the phone number type, which is a combination of TypeFlag.
  292. QXmppVCardPhone::Type QXmppVCardPhone::type() const
  293. {
  294. return d->type;
  295. }
  296. /// Sets the phone number \a type, which is a combination of TypeFlag.
  297. void QXmppVCardPhone::setType(QXmppVCardPhone::Type type)
  298. {
  299. d->type = type;
  300. }
  301. /// \cond
  302. void QXmppVCardPhone::parse(const QDomElement &element)
  303. {
  304. if (!element.firstChildElement("HOME").isNull())
  305. d->type |= Home;
  306. if (!element.firstChildElement("WORK").isNull())
  307. d->type |= Work;
  308. if (!element.firstChildElement("VOICE").isNull())
  309. d->type |= Voice;
  310. if (!element.firstChildElement("FAX").isNull())
  311. d->type |= Fax;
  312. if (!element.firstChildElement("PAGER").isNull())
  313. d->type |= Pager;
  314. if (!element.firstChildElement("MSG").isNull())
  315. d->type |= Messaging;
  316. if (!element.firstChildElement("CELL").isNull())
  317. d->type |= Cell;
  318. if (!element.firstChildElement("VIDEO").isNull())
  319. d->type |= Video;
  320. if (!element.firstChildElement("BBS").isNull())
  321. d->type |= BBS;
  322. if (!element.firstChildElement("MODEM").isNull())
  323. d->type |= Modem;
  324. if (!element.firstChildElement("ISDN").isNull())
  325. d->type |= ISDN;
  326. if (!element.firstChildElement("PCS").isNull())
  327. d->type |= PCS;
  328. if (!element.firstChildElement("PREF").isNull())
  329. d->type |= Preferred;
  330. d->number = element.firstChildElement("NUMBER").text();
  331. }
  332. void QXmppVCardPhone::toXml(QXmlStreamWriter *writer) const
  333. {
  334. writer->writeStartElement("PHONE");
  335. if (d->type & Home)
  336. writer->writeEmptyElement("HOME");
  337. if (d->type & Work)
  338. writer->writeEmptyElement("WORK");
  339. if (d->type & Voice)
  340. writer->writeEmptyElement("VOICE");
  341. if (d->type & Fax)
  342. writer->writeEmptyElement("FAX");
  343. if (d->type & Pager)
  344. writer->writeEmptyElement("PAGER");
  345. if (d->type & Messaging)
  346. writer->writeEmptyElement("MSG");
  347. if (d->type & Cell)
  348. writer->writeEmptyElement("CELL");
  349. if (d->type & Video)
  350. writer->writeEmptyElement("VIDEO");
  351. if (d->type & BBS)
  352. writer->writeEmptyElement("BBS");
  353. if (d->type & Modem)
  354. writer->writeEmptyElement("MODEM");
  355. if (d->type & ISDN)
  356. writer->writeEmptyElement("ISDN");
  357. if (d->type & PCS)
  358. writer->writeEmptyElement("PCS");
  359. if (d->type & Preferred)
  360. writer->writeEmptyElement("PREF");
  361. writer->writeTextElement("NUMBER", d->number);
  362. writer->writeEndElement();
  363. }
  364. /// \endcond
  365. class QXmppVCardIqPrivate : public QSharedData
  366. {
  367. public:
  368. QDate birthday;
  369. QString description;
  370. QString firstName;
  371. QString fullName;
  372. QString lastName;
  373. QString middleName;
  374. QString nickName;
  375. QString url;
  376. // not as 64 base
  377. QByteArray photo;
  378. QString photoType;
  379. QList<QXmppVCardAddress> addresses;
  380. QList<QXmppVCardEmail> emails;
  381. QList<QXmppVCardPhone> phones;
  382. };
  383. /// Constructs a QXmppVCardIq for the specified recipient.
  384. ///
  385. /// \param jid
  386. QXmppVCardIq::QXmppVCardIq(const QString& jid)
  387. : QXmppIq()
  388. , d(new QXmppVCardIqPrivate)
  389. {
  390. // for self jid should be empty
  391. setTo(jid);
  392. }
  393. /// Constructs a copy of \a other.
  394. QXmppVCardIq::QXmppVCardIq(const QXmppVCardIq &other)
  395. : QXmppIq(other)
  396. , d(other.d)
  397. {
  398. }
  399. QXmppVCardIq::~QXmppVCardIq()
  400. {
  401. }
  402. /// Assigns \a other to this vCard IQ.
  403. QXmppVCardIq& QXmppVCardIq::operator=(const QXmppVCardIq &other)
  404. {
  405. QXmppIq::operator=(other);
  406. d = other.d;
  407. return *this;
  408. }
  409. /// Returns the date of birth of the individual associated with the vCard.
  410. ///
  411. QDate QXmppVCardIq::birthday() const
  412. {
  413. return d->birthday;
  414. }
  415. /// Sets the date of birth of the individual associated with the vCard.
  416. ///
  417. /// \param birthday
  418. void QXmppVCardIq::setBirthday(const QDate &birthday)
  419. {
  420. d->birthday = birthday;
  421. }
  422. /// Returns the free-form descriptive text.
  423. QString QXmppVCardIq::description() const
  424. {
  425. return d->description;
  426. }
  427. /// Sets the free-form descriptive text.
  428. void QXmppVCardIq::setDescription(const QString &description)
  429. {
  430. d->description = description;
  431. }
  432. /// Returns the email address.
  433. ///
  434. QString QXmppVCardIq::email() const
  435. {
  436. if (d->emails.isEmpty())
  437. return QString();
  438. else
  439. return d->emails.first().address();
  440. }
  441. /// Sets the email address.
  442. ///
  443. /// \param email
  444. void QXmppVCardIq::setEmail(const QString &email)
  445. {
  446. QXmppVCardEmail first;
  447. first.setAddress(email);
  448. first.setType(QXmppVCardEmail::Internet);
  449. d->emails = QList<QXmppVCardEmail>() << first;
  450. }
  451. /// Returns the first name.
  452. ///
  453. QString QXmppVCardIq::firstName() const
  454. {
  455. return d->firstName;
  456. }
  457. /// Sets the first name.
  458. ///
  459. /// \param firstName
  460. void QXmppVCardIq::setFirstName(const QString &firstName)
  461. {
  462. d->firstName = firstName;
  463. }
  464. /// Returns the full name.
  465. ///
  466. QString QXmppVCardIq::fullName() const
  467. {
  468. return d->fullName;
  469. }
  470. /// Sets the full name.
  471. ///
  472. /// \param fullName
  473. void QXmppVCardIq::setFullName(const QString &fullName)
  474. {
  475. d->fullName = fullName;
  476. }
  477. /// Returns the last name.
  478. ///
  479. QString QXmppVCardIq::lastName() const
  480. {
  481. return d->lastName;
  482. }
  483. /// Sets the last name.
  484. ///
  485. /// \param lastName
  486. void QXmppVCardIq::setLastName(const QString &lastName)
  487. {
  488. d->lastName = lastName;
  489. }
  490. /// Returns the middle name.
  491. ///
  492. QString QXmppVCardIq::middleName() const
  493. {
  494. return d->middleName;
  495. }
  496. /// Sets the middle name.
  497. ///
  498. /// \param middleName
  499. void QXmppVCardIq::setMiddleName(const QString &middleName)
  500. {
  501. d->middleName = middleName;
  502. }
  503. /// Returns the nickname.
  504. ///
  505. QString QXmppVCardIq::nickName() const
  506. {
  507. return d->nickName;
  508. }
  509. /// Sets the nickname.
  510. ///
  511. /// \param nickName
  512. void QXmppVCardIq::setNickName(const QString &nickName)
  513. {
  514. d->nickName = nickName;
  515. }
  516. /// Returns the URL associated with the vCard. It can represent the user's
  517. /// homepage or a location at which you can find real-time information about
  518. /// the vCard.
  519. QString QXmppVCardIq::url() const
  520. {
  521. return d->url;
  522. }
  523. /// Sets the URL associated with the vCard. It can represent the user's
  524. /// homepage or a location at which you can find real-time information about
  525. /// the vCard.
  526. ///
  527. /// \param url
  528. void QXmppVCardIq::setUrl(const QString& url)
  529. {
  530. d->url = url;
  531. }
  532. /// Returns the photo's binary contents.
  533. ///
  534. /// If you want to use the photo as a QImage you can use:
  535. ///
  536. /// \code
  537. /// QBuffer buffer;
  538. /// buffer.setData(myCard.photo());
  539. /// buffer.open(QIODevice::ReadOnly);
  540. /// QImageReader imageReader(&buffer);
  541. /// QImage myImage = imageReader.read();
  542. /// \endcode
  543. QByteArray QXmppVCardIq::photo() const
  544. {
  545. return d->photo;
  546. }
  547. /// Sets the photo's binary contents.
  548. void QXmppVCardIq::setPhoto(const QByteArray& photo)
  549. {
  550. d->photo = photo;
  551. }
  552. /// Returns the photo's MIME type.
  553. QString QXmppVCardIq::photoType() const
  554. {
  555. return d->photoType;
  556. }
  557. /// Sets the photo's MIME type.
  558. void QXmppVCardIq::setPhotoType(const QString& photoType)
  559. {
  560. d->photoType = photoType;
  561. }
  562. /// Returns the addresses.
  563. QList<QXmppVCardAddress> QXmppVCardIq::addresses() const
  564. {
  565. return d->addresses;
  566. }
  567. /// Sets the addresses.
  568. void QXmppVCardIq::setAddresses(const QList<QXmppVCardAddress> &addresses)
  569. {
  570. d->addresses = addresses;
  571. }
  572. /// Returns the e-mail addresses.
  573. QList<QXmppVCardEmail> QXmppVCardIq::emails() const
  574. {
  575. return d->emails;
  576. }
  577. /// Sets the e-mail addresses.
  578. void QXmppVCardIq::setEmails(const QList<QXmppVCardEmail> &emails)
  579. {
  580. d->emails = emails;
  581. }
  582. /// Returns the phone numbers.
  583. QList<QXmppVCardPhone> QXmppVCardIq::phones() const
  584. {
  585. return d->phones;
  586. }
  587. /// Sets the phone numbers.
  588. void QXmppVCardIq::setPhones(const QList<QXmppVCardPhone> &phones)
  589. {
  590. d->phones = phones;
  591. }
  592. /// \cond
  593. bool QXmppVCardIq::isVCard(const QDomElement &nodeRecv)
  594. {
  595. return nodeRecv.firstChildElement("vCard").namespaceURI() == ns_vcard;
  596. }
  597. void QXmppVCardIq::parseElementFromChild(const QDomElement& nodeRecv)
  598. {
  599. // vCard
  600. QDomElement cardElement = nodeRecv.firstChildElement("vCard");
  601. d->birthday = QDate::fromString(cardElement.firstChildElement("BDAY").text(), "yyyy-MM-dd");
  602. d->description = cardElement.firstChildElement("DESC").text();
  603. d->fullName = cardElement.firstChildElement("FN").text();
  604. d->nickName = cardElement.firstChildElement("NICKNAME").text();
  605. QDomElement nameElement = cardElement.firstChildElement("N");
  606. d->firstName = nameElement.firstChildElement("GIVEN").text();
  607. d->lastName = nameElement.firstChildElement("FAMILY").text();
  608. d->middleName = nameElement.firstChildElement("MIDDLE").text();
  609. d->url = cardElement.firstChildElement("URL").text();
  610. QDomElement photoElement = cardElement.firstChildElement("PHOTO");
  611. QByteArray base64data = photoElement.
  612. firstChildElement("BINVAL").text().toAscii();
  613. d->photo = QByteArray::fromBase64(base64data);
  614. d->photoType = photoElement.firstChildElement("TYPE").text();
  615. QDomElement child = cardElement.firstChildElement();
  616. while (!child.isNull()) {
  617. if (child.tagName() == "ADR") {
  618. QXmppVCardAddress address;
  619. address.parse(child);
  620. d->addresses << address;
  621. } else if (child.tagName() == "EMAIL") {
  622. QXmppVCardEmail email;
  623. email.parse(child);
  624. d->emails << email;
  625. } else if (child.tagName() == "PHONE") {
  626. QXmppVCardPhone phone;
  627. phone.parse(child);
  628. d->phones << phone;
  629. }
  630. child = child.nextSiblingElement();
  631. }
  632. }
  633. void QXmppVCardIq::toXmlElementFromChild(QXmlStreamWriter *writer) const
  634. {
  635. writer->writeStartElement("vCard");
  636. writer->writeAttribute("xmlns", ns_vcard);
  637. foreach (const QXmppVCardAddress &address, d->addresses)
  638. address.toXml(writer);
  639. if (d->birthday.isValid())
  640. helperToXmlAddTextElement(writer, "BDAY", d->birthday.toString("yyyy-MM-dd"));
  641. if (!d->description.isEmpty())
  642. helperToXmlAddTextElement(writer, "DESC", d->description);
  643. foreach (const QXmppVCardEmail &email, d->emails)
  644. email.toXml(writer);
  645. if (!d->fullName.isEmpty())
  646. helperToXmlAddTextElement(writer, "FN", d->fullName);
  647. if(!d->nickName.isEmpty())
  648. helperToXmlAddTextElement(writer, "NICKNAME", d->nickName);
  649. if (!d->firstName.isEmpty() ||
  650. !d->lastName.isEmpty() ||
  651. !d->middleName.isEmpty())
  652. {
  653. writer->writeStartElement("N");
  654. if (!d->firstName.isEmpty())
  655. helperToXmlAddTextElement(writer, "GIVEN", d->firstName);
  656. if (!d->lastName.isEmpty())
  657. helperToXmlAddTextElement(writer, "FAMILY", d->lastName);
  658. if (!d->middleName.isEmpty())
  659. helperToXmlAddTextElement(writer, "MIDDLE", d->middleName);
  660. writer->writeEndElement();
  661. }
  662. foreach (const QXmppVCardPhone &phone, d->phones)
  663. phone.toXml(writer);
  664. if(!photo().isEmpty())
  665. {
  666. writer->writeStartElement("PHOTO");
  667. QString photoType = d->photoType;
  668. if (photoType.isEmpty())
  669. photoType = getImageType(d->photo);
  670. helperToXmlAddTextElement(writer, "TYPE", photoType);
  671. helperToXmlAddTextElement(writer, "BINVAL", d->photo.toBase64());
  672. writer->writeEndElement();
  673. }
  674. if (!d->url.isEmpty())
  675. helperToXmlAddTextElement(writer, "URL", d->url);
  676. writer->writeEndElement();
  677. }
  678. /// \endcond