summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften')
-rw-r--r--Swiften/Elements/VCard.cpp26
-rw-r--r--Swiften/Elements/VCard.h52
-rw-r--r--Swiften/Parser/PayloadParsers/RosterParser.cpp1
-rw-r--r--Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp59
-rw-r--r--Swiften/Parser/PayloadParsers/VCardParser.cpp87
-rw-r--r--Swiften/Parser/PayloadParsers/VCardParser.h2
-rw-r--r--Swiften/SConscript2
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/VCardSerializerTest.cpp84
-rw-r--r--Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp46
9 files changed, 338 insertions, 21 deletions
diff --git a/Swiften/Elements/VCard.cpp b/Swiften/Elements/VCard.cpp
new file mode 100644
index 0000000..8262e07
--- /dev/null
+++ b/Swiften/Elements/VCard.cpp
@@ -0,0 +1,26 @@
1/*
2 * Copyright (c) 2010 Remko Tronçon
3 * Licensed under the GNU General Public License v3.
4 * See Documentation/Licenses/GPLv3.txt for more information.
5 */
6
7#include "Swiften/Elements/VCard.h"
8
9#include "Swiften/Base/foreach.h"
10
11namespace Swift {
12
13VCard::EMailAddress VCard::getPreferredEMailAddress() const {
14 foreach(const EMailAddress& address, emailAddresses_) {
15 if (address.isPreferred) {
16 return address;
17 }
18 }
19 if (emailAddresses_.size() > 0) {
20 return emailAddresses_[0];
21 }
22 return EMailAddress();
23}
24
25
26}
diff --git a/Swiften/Elements/VCard.h b/Swiften/Elements/VCard.h
index 60f94b1..15173f1 100644
--- a/Swiften/Elements/VCard.h
+++ b/Swiften/Elements/VCard.h
@@ -12,38 +12,84 @@
12#include "Swiften/Elements/Payload.h" 12#include "Swiften/Elements/Payload.h"
13 13
14namespace Swift { 14namespace Swift {
15 class VCard : public Payload, public Shared<VCard> { 15 class VCard : public Payload, public Shared<VCard> {
16 public: 16 public:
17 struct EMailAddress {
18 EMailAddress() : isHome(false), isWork(false), isInternet(false), isPreferred(false), isX400(false) {
19 }
20
21 bool isHome;
22 bool isWork;
23 bool isInternet;
24 bool isPreferred;
25 bool isX400;
26 String address;
27 };
28
17 VCard() {} 29 VCard() {}
18 30
31 void setVersion(const String& version) { version_ = version; }
32 const String& getVersion() const { return version_; }
33
19 void setFullName(const String& fullName) { fullName_ = fullName; } 34 void setFullName(const String& fullName) { fullName_ = fullName; }
20 const String& getFullName() const { return fullName_; } 35 const String& getFullName() const { return fullName_; }
21 36
22 void setFamilyName(const String& familyName) { familyName_ = familyName; } 37 void setFamilyName(const String& familyName) { familyName_ = familyName; }
23 const String& getFamilyName() const { return familyName_; } 38 const String& getFamilyName() const { return familyName_; }
24 39
25 void setGivenName(const String& givenName) { givenName_ = givenName; } 40 void setGivenName(const String& givenName) { givenName_ = givenName; }
26 const String& getGivenName() const { return givenName_; } 41 const String& getGivenName() const { return givenName_; }
27 42
28 void setEMail(const String& email) { email_ = email; } 43 void setMiddleName(const String& middleName) { middleName_ = middleName; }
29 const String& getEMail() const { return email_; } 44 const String& getMiddleName() const { return middleName_; }
45
46 void setPrefix(const String& prefix) { prefix_ = prefix; }
47 const String& getPrefix() const { return prefix_; }
48
49 void setSuffix(const String& suffix) { suffix_ = suffix; }
50 const String& getSuffix() const { return suffix_; }
51
52
53 //void setEMailAddress(const String& email) { email_ = email; }
54 //const String& getEMailAddress() const { return email_; }
30 55
31 void setNickname(const String& nick) { nick_ = nick; } 56 void setNickname(const String& nick) { nick_ = nick; }
32 const String& getNickname() const { return nick_; } 57 const String& getNickname() const { return nick_; }
33 58
34 void setPhoto(const ByteArray& photo) { photo_ = photo; } 59 void setPhoto(const ByteArray& photo) { photo_ = photo; }
35 const ByteArray& getPhoto() { return photo_; } 60 const ByteArray& getPhoto() { return photo_; }
36 61
37 void setPhotoType(const String& photoType) { photoType_ = photoType; } 62 void setPhotoType(const String& photoType) { photoType_ = photoType; }
38 const String& getPhotoType() { return photoType_; } 63 const String& getPhotoType() { return photoType_; }
39 64
65 const String& getUnknownContent() const { return unknownContent_; }
66 void addUnknownContent(const String& c) {
67 unknownContent_ += c;
68 }
69
70 const std::vector<EMailAddress> getEMailAddresses() const {
71 return emailAddresses_;
72 }
73
74 void addEMailAddress(const EMailAddress& email) {
75 emailAddresses_.push_back(email);
76 }
77
78 EMailAddress getPreferredEMailAddress() const;
79
40 private: 80 private:
81 String version_;
41 String fullName_; 82 String fullName_;
42 String familyName_; 83 String familyName_;
43 String givenName_; 84 String givenName_;
44 String email_; 85 String middleName_;
86 String prefix_;
87 String suffix_;
88 //String email_;
45 ByteArray photo_; 89 ByteArray photo_;
46 String photoType_; 90 String photoType_;
47 String nick_; 91 String nick_;
92 String unknownContent_;
93 std::vector<EMailAddress> emailAddresses_;
48 }; 94 };
49} 95}
diff --git a/Swiften/Parser/PayloadParsers/RosterParser.cpp b/Swiften/Parser/PayloadParsers/RosterParser.cpp
index c3a35b6..6db2b30 100644
--- a/Swiften/Parser/PayloadParsers/RosterParser.cpp
+++ b/Swiften/Parser/PayloadParsers/RosterParser.cpp
@@ -69,10 +69,11 @@ void RosterParser::handleEndElement(const String& element, const String& ns) {
69 } 69 }
70 else if (level_ == ItemLevel) { 70 else if (level_ == ItemLevel) {
71 if (unknownContentParser_) { 71 if (unknownContentParser_) {
72 unknownContentParser_->handleEndElement(element, ns); 72 unknownContentParser_->handleEndElement(element, ns);
73 currentItem_.addUnknownContent(unknownContentParser_->getResult()); 73 currentItem_.addUnknownContent(unknownContentParser_->getResult());
74 delete unknownContentParser_;
74 unknownContentParser_ = NULL; 75 unknownContentParser_ = NULL;
75 } 76 }
76 else if (element == "group") { 77 else if (element == "group") {
77 currentItem_.addGroup(currentText_); 78 currentItem_.addGroup(currentText_);
78 } 79 }
diff --git a/Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp
index 999eb34..dfcc0ec 100644
--- a/Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp
+++ b/Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp
@@ -10,19 +10,72 @@
10#include "Swiften/Parser/PayloadParsers/VCardParser.h" 10#include "Swiften/Parser/PayloadParsers/VCardParser.h"
11#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" 11#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h"
12 12
13using namespace Swift; 13using namespace Swift;
14 14
15class VCardParserTest : public CppUnit::TestFixture 15class VCardParserTest : public CppUnit::TestFixture {
16{
17 CPPUNIT_TEST_SUITE(VCardParserTest); 16 CPPUNIT_TEST_SUITE(VCardParserTest);
17 CPPUNIT_TEST(testParse);
18 CPPUNIT_TEST(testParse_Photo); 18 CPPUNIT_TEST(testParse_Photo);
19 CPPUNIT_TEST(testParse_Nickname); 19 CPPUNIT_TEST(testParse_Nickname);
20 CPPUNIT_TEST_SUITE_END(); 20 CPPUNIT_TEST_SUITE_END();
21 21
22 public: 22 public:
23 VCardParserTest() {} 23 void testParse() {
24 PayloadsParserTester parser;
25
26 CPPUNIT_ASSERT(parser.parse(
27 "<vCard xmlns=\"vcard-temp\">"
28 "<VERSION>2.0</VERSION>"
29 "<FN>Alice In Wonderland</FN>"
30 "<N>"
31 "<FAMILY>Wonderland</FAMILY>"
32 "<GIVEN>Alice</GIVEN>"
33 "<MIDDLE>In</MIDDLE>"
34 "<PREFIX>Mrs</PREFIX>"
35 "<SUFFIX>PhD</SUFFIX>"
36 "</N>"
37 "<EMAIL>"
38 "<USERID>alice@wonderland.lit</USERID>"
39 "<HOME/>"
40 "<INTERNET/>"
41 "<PREF/>"
42 "</EMAIL>"
43 "<EMAIL>"
44 "<USERID>alice@teaparty.lit</USERID>"
45 "<WORK/>"
46 "<X400/>"
47 "</EMAIL>"
48 "<NICKNAME>DreamGirl</NICKNAME>"
49 "<BDAY>1234</BDAY>"
50 "<MAILER>mutt</MAILER>"
51 "</vCard>"));
52
53 boost::shared_ptr<VCard> payload = boost::dynamic_pointer_cast<VCard>(parser.getPayload());
54 CPPUNIT_ASSERT_EQUAL(String("2.0"), payload->getVersion());
55 CPPUNIT_ASSERT_EQUAL(String("Alice In Wonderland"), payload->getFullName());
56 CPPUNIT_ASSERT_EQUAL(String("Alice"), payload->getGivenName());
57 CPPUNIT_ASSERT_EQUAL(String("In"), payload->getMiddleName());
58 CPPUNIT_ASSERT_EQUAL(String("Wonderland"), payload->getFamilyName());
59 CPPUNIT_ASSERT_EQUAL(String("Mrs"), payload->getPrefix());
60 CPPUNIT_ASSERT_EQUAL(String("PhD"), payload->getSuffix());
61 CPPUNIT_ASSERT_EQUAL(String("DreamGirl"), payload->getNickname());
62 CPPUNIT_ASSERT_EQUAL(String("<BDAY xmlns=\"vcard-temp\">1234</BDAY><MAILER xmlns=\"vcard-temp\">mutt</MAILER>"), payload->getUnknownContent());
63 CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(payload->getEMailAddresses().size()));
64 CPPUNIT_ASSERT_EQUAL(String("alice@wonderland.lit"), payload->getEMailAddresses()[0].address);
65 CPPUNIT_ASSERT(payload->getEMailAddresses()[0].isHome);
66 CPPUNIT_ASSERT(payload->getEMailAddresses()[0].isInternet);
67 CPPUNIT_ASSERT(payload->getEMailAddresses()[0].isPreferred);
68 CPPUNIT_ASSERT(!payload->getEMailAddresses()[0].isWork);
69 CPPUNIT_ASSERT(!payload->getEMailAddresses()[0].isX400);
70 CPPUNIT_ASSERT_EQUAL(String("alice@teaparty.lit"), payload->getEMailAddresses()[1].address);
71 CPPUNIT_ASSERT(!payload->getEMailAddresses()[1].isHome);
72 CPPUNIT_ASSERT(!payload->getEMailAddresses()[1].isInternet);
73 CPPUNIT_ASSERT(!payload->getEMailAddresses()[1].isPreferred);
74 CPPUNIT_ASSERT(payload->getEMailAddresses()[1].isWork);
75 CPPUNIT_ASSERT(payload->getEMailAddresses()[1].isX400);
76 }
24 77
25 void testParse_Photo() { 78 void testParse_Photo() {
26 PayloadsParserTester parser; 79 PayloadsParserTester parser;
27 80
28 CPPUNIT_ASSERT(parser.parse( 81 CPPUNIT_ASSERT(parser.parse(
diff --git a/Swiften/Parser/PayloadParsers/VCardParser.cpp b/Swiften/Parser/PayloadParsers/VCardParser.cpp
index 338efc6..2f1f8dc 100644
--- a/Swiften/Parser/PayloadParsers/VCardParser.cpp
+++ b/Swiften/Parser/PayloadParsers/VCardParser.cpp
@@ -5,48 +5,111 @@
5 */ 5 */
6 6
7#include "Swiften/Parser/PayloadParsers/VCardParser.h" 7#include "Swiften/Parser/PayloadParsers/VCardParser.h"
8#include "Swiften/Base/foreach.h" 8#include "Swiften/Base/foreach.h"
9#include "Swiften/StringCodecs/Base64.h" 9#include "Swiften/StringCodecs/Base64.h"
10#include "Swiften/Parser/SerializingParser.h"
10 11
11namespace Swift { 12namespace Swift {
12 13
13VCardParser::VCardParser() { 14VCardParser::VCardParser() : unknownContentParser_(NULL) {
14} 15}
15 16
16void VCardParser::handleStartElement(const String& element, const String&, const AttributeMap&) { 17void VCardParser::handleStartElement(const String& element, const String& ns, const AttributeMap& attributes) {
17 elementStack_.push_back(element); 18 elementStack_.push_back(element);
19 String elementHierarchy = getElementHierarchy();
20 if (elementHierarchy == "/vCard/EMAIL") {
21 currentEMailAddress_ = VCard::EMailAddress();
22 }
23 if (elementStack_.size() == 2) {
24 assert(!unknownContentParser_);
25 unknownContentParser_ = new SerializingParser();
26 unknownContentParser_->handleStartElement(element, ns, attributes);
27 }
28 else if (unknownContentParser_) {
29 unknownContentParser_->handleStartElement(element, ns, attributes);
30 }
31
18 currentText_ = ""; 32 currentText_ = "";
19} 33}
20 34
21void VCardParser::handleEndElement(const String&, const String&) { 35void VCardParser::handleEndElement(const String& element, const String& ns) {
22 String elementHierarchy = getElementHierarchy(); 36 if (unknownContentParser_) {
23 if (elementHierarchy == "/vCard/PHOTO/TYPE") { 37 unknownContentParser_->handleEndElement(element, ns);
24 getPayloadInternal()->setPhotoType(currentText_);
25 }
26 else if (elementHierarchy == "/vCard/PHOTO/BINVAL") {
27 getPayloadInternal()->setPhoto(Base64::decode(currentText_));
28 } 38 }
29 else if (elementHierarchy == "/vCard/NICKNAME") { 39
30 getPayloadInternal()->setNickname(currentText_); 40 String elementHierarchy = getElementHierarchy();
41 if (elementHierarchy == "/vCard/VERSION") {
42 getPayloadInternal()->setVersion(currentText_);
31 } 43 }
32 else if (elementHierarchy == "/vCard/FN") { 44 else if (elementHierarchy == "/vCard/FN") {
33 getPayloadInternal()->setFullName(currentText_); 45 getPayloadInternal()->setFullName(currentText_);
34 } 46 }
35 else if (elementHierarchy == "/vCard/N/FAMILY") { 47 else if (elementHierarchy == "/vCard/N/FAMILY") {
36 getPayloadInternal()->setFamilyName(currentText_); 48 getPayloadInternal()->setFamilyName(currentText_);
37 } 49 }
38 else if (elementHierarchy == "/vCard/N/GIVEN") { 50 else if (elementHierarchy == "/vCard/N/GIVEN") {
39 getPayloadInternal()->setGivenName(currentText_); 51 getPayloadInternal()->setGivenName(currentText_);
40 } 52 }
53 else if (elementHierarchy == "/vCard/N/MIDDLE") {
54 getPayloadInternal()->setMiddleName(currentText_);
55 }
56 else if (elementHierarchy == "/vCard/N/PREFIX") {
57 getPayloadInternal()->setPrefix(currentText_);
58 }
59 else if (elementHierarchy == "/vCard/N/SUFFIX") {
60 getPayloadInternal()->setSuffix(currentText_);
61 }
62 else if (elementHierarchy == "/vCard/N") {
63 }
64 else if (elementHierarchy == "/vCard/NICKNAME") {
65 getPayloadInternal()->setNickname(currentText_);
66 }
67 else if (elementHierarchy == "/vCard/PHOTO/TYPE") {
68 getPayloadInternal()->setPhotoType(currentText_);
69 }
70 else if (elementHierarchy == "/vCard/PHOTO/BINVAL") {
71 getPayloadInternal()->setPhoto(Base64::decode(currentText_));
72 }
73 else if (elementHierarchy == "/vCard/PHOTO") {
74 }
41 else if (elementHierarchy == "/vCard/EMAIL/USERID") { 75 else if (elementHierarchy == "/vCard/EMAIL/USERID") {
42 getPayloadInternal()->setEMail(currentText_); 76 currentEMailAddress_.address = currentText_;
77 }
78 else if (elementHierarchy == "/vCard/EMAIL/HOME") {
79 currentEMailAddress_.isHome = true;
80 }
81 else if (elementHierarchy == "/vCard/EMAIL/WORK") {
82 currentEMailAddress_.isWork = true;
83 }
84 else if (elementHierarchy == "/vCard/EMAIL/INTERNET") {
85 currentEMailAddress_.isInternet = true;
86 }
87 else if (elementHierarchy == "/vCard/EMAIL/X400") {
88 currentEMailAddress_.isX400 = true;
89 }
90 else if (elementHierarchy == "/vCard/EMAIL/PREF") {
91 currentEMailAddress_.isPreferred = true;
92 }
93 else if (elementHierarchy == "/vCard/EMAIL") {
94 getPayloadInternal()->addEMailAddress(currentEMailAddress_);
95 }
96 else if (elementStack_.size() == 2 && unknownContentParser_) {
97 getPayloadInternal()->addUnknownContent(unknownContentParser_->getResult());
98 }
99
100 if (elementStack_.size() == 2 && unknownContentParser_) {
101 delete unknownContentParser_;
102 unknownContentParser_ = NULL;
43 } 103 }
44 elementStack_.pop_back(); 104 elementStack_.pop_back();
45} 105}
46 106
47void VCardParser::handleCharacterData(const String& text) { 107void VCardParser::handleCharacterData(const String& text) {
108 if (unknownContentParser_) {
109 unknownContentParser_->handleCharacterData(text);
110 }
48 currentText_ += text; 111 currentText_ += text;
49} 112}
50 113
51String VCardParser::getElementHierarchy() const { 114String VCardParser::getElementHierarchy() const {
52 String result; 115 String result;
diff --git a/Swiften/Parser/PayloadParsers/VCardParser.h b/Swiften/Parser/PayloadParsers/VCardParser.h
index d22f8f5..f912ff1 100644
--- a/Swiften/Parser/PayloadParsers/VCardParser.h
+++ b/Swiften/Parser/PayloadParsers/VCardParser.h
@@ -23,8 +23,10 @@ namespace Swift {
23 private: 23 private:
24 String getElementHierarchy() const; 24 String getElementHierarchy() const;
25 25
26 private: 26 private:
27 std::vector<String> elementStack_; 27 std::vector<String> elementStack_;
28 VCard::EMailAddress currentEMailAddress_;
29 SerializingParser* unknownContentParser_;
28 String currentText_; 30 String currentText_;
29 }; 31 };
30} 32}
diff --git a/Swiften/SConscript b/Swiften/SConscript
index a23efa0..3d82cfa 100644
--- a/Swiften/SConscript
+++ b/Swiften/SConscript
@@ -41,10 +41,11 @@ if env["SCONS_STAGE"] == "build" :
41 "Elements/Element.cpp", 41 "Elements/Element.cpp",
42 "Elements/IQ.cpp", 42 "Elements/IQ.cpp",
43 "Elements/Payload.cpp", 43 "Elements/Payload.cpp",
44 "Elements/RosterPayload.cpp", 44 "Elements/RosterPayload.cpp",
45 "Elements/Stanza.cpp", 45 "Elements/Stanza.cpp",
46 "Elements/VCard.cpp",
46 "MUC/MUC.cpp", 47 "MUC/MUC.cpp",
47 "MUC/MUCOccupant.cpp", 48 "MUC/MUCOccupant.cpp",
48 "MUC/MUCRegistry.cpp", 49 "MUC/MUCRegistry.cpp",
49 "MUC/MUCBookmarkManager.cpp", 50 "MUC/MUCBookmarkManager.cpp",
50 "Notifier/Notifier.cpp", 51 "Notifier/Notifier.cpp",
@@ -216,10 +217,11 @@ if env["SCONS_STAGE"] == "build" :
216 File("Serializer/PayloadSerializers/UnitTest/SecurityLabelsCatalogSerializerTest.cpp"), 217 File("Serializer/PayloadSerializers/UnitTest/SecurityLabelsCatalogSerializerTest.cpp"),
217 File("Serializer/PayloadSerializers/UnitTest/SoftwareVersionSerializerTest.cpp"), 218 File("Serializer/PayloadSerializers/UnitTest/SoftwareVersionSerializerTest.cpp"),
218 File("Serializer/PayloadSerializers/UnitTest/StatusSerializerTest.cpp"), 219 File("Serializer/PayloadSerializers/UnitTest/StatusSerializerTest.cpp"),
219 File("Serializer/PayloadSerializers/UnitTest/StatusShowSerializerTest.cpp"), 220 File("Serializer/PayloadSerializers/UnitTest/StatusShowSerializerTest.cpp"),
220 File("Serializer/PayloadSerializers/UnitTest/VCardUpdateSerializerTest.cpp"), 221 File("Serializer/PayloadSerializers/UnitTest/VCardUpdateSerializerTest.cpp"),
222 File("Serializer/PayloadSerializers/UnitTest/VCardSerializerTest.cpp"),
221 File("Serializer/PayloadSerializers/UnitTest/StorageSerializerTest.cpp"), 223 File("Serializer/PayloadSerializers/UnitTest/StorageSerializerTest.cpp"),
222 File("Serializer/PayloadSerializers/UnitTest/PrivateStorageSerializerTest.cpp"), 224 File("Serializer/PayloadSerializers/UnitTest/PrivateStorageSerializerTest.cpp"),
223 File("Serializer/UnitTest/StreamFeaturesSerializerTest.cpp"), 225 File("Serializer/UnitTest/StreamFeaturesSerializerTest.cpp"),
224 File("Serializer/UnitTest/AuthSuccessSerializerTest.cpp"), 226 File("Serializer/UnitTest/AuthSuccessSerializerTest.cpp"),
225 File("Serializer/UnitTest/AuthChallengeSerializerTest.cpp"), 227 File("Serializer/UnitTest/AuthChallengeSerializerTest.cpp"),
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/VCardSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/VCardSerializerTest.cpp
new file mode 100644
index 0000000..11b24dc
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/VCardSerializerTest.cpp
@@ -0,0 +1,84 @@
1/*
2 * Copyright (c) 2010 Remko Tronçon
3 * Licensed under the GNU General Public License v3.
4 * See Documentation/Licenses/GPLv3.txt for more information.
5 */
6
7#include <cppunit/extensions/HelperMacros.h>
8#include <cppunit/extensions/TestFactoryRegistry.h>
9
10#include "Swiften/Serializer/PayloadSerializers/VCardSerializer.h"
11
12using namespace Swift;
13
14class VCardSerializerTest : public CppUnit::TestFixture
15{
16 CPPUNIT_TEST_SUITE(VCardSerializerTest);
17 CPPUNIT_TEST(testSerialize);
18 CPPUNIT_TEST_SUITE_END();
19
20 public:
21 void testSerialize() {
22 VCardSerializer testling;
23 boost::shared_ptr<VCard> vcard(new VCard());
24 vcard->setVersion("2.0");
25 vcard->setFullName("Alice In Wonderland");
26 vcard->setPrefix("Mrs");
27 vcard->setGivenName("Alice");
28 vcard->setMiddleName("In");
29 vcard->setFamilyName("Wonderland");
30 vcard->setSuffix("PhD");
31 vcard->setNickname("DreamGirl");
32 vcard->setPhoto("abcdef");
33 vcard->setPhotoType("image/png");
34 vcard->addUnknownContent("<BDAY>1234</BDAY><MAILER>mutt</MAILER>");
35
36 VCard::EMailAddress address1;
37 address1.address = "alice@wonderland.lit";
38 address1.isHome = true;
39 address1.isPreferred = true;
40 address1.isInternet = true;
41 vcard->addEMailAddress(address1);
42
43 VCard::EMailAddress address2;
44 address2.address = "alice@teaparty.lit";
45 address2.isWork = true;
46 address2.isX400 = true;
47 vcard->addEMailAddress(address2);
48
49 String expectedResult =
50 "<vCard xmlns=\"vcard-temp\">"
51 "<VERSION>2.0</VERSION>"
52 "<FN>Alice In Wonderland</FN>"
53 "<N>"
54 "<FAMILY>Wonderland</FAMILY>"
55 "<GIVEN>Alice</GIVEN>"
56 "<MIDDLE>In</MIDDLE>"
57 "<PREFIX>Mrs</PREFIX>"
58 "<SUFFIX>PhD</SUFFIX>"
59 "</N>"
60 "<EMAIL>"
61 "<USERID>alice@wonderland.lit</USERID>"
62 "<HOME/>"
63 "<INTERNET/>"
64 "<PREF/>"
65 "</EMAIL>"
66 "<EMAIL>"
67 "<USERID>alice@teaparty.lit</USERID>"
68 "<WORK/>"
69 "<X400/>"
70 "</EMAIL>"
71 "<NICKNAME>DreamGirl</NICKNAME>"
72 "<PHOTO>"
73 "<TYPE>image/png</TYPE>"
74 "<BINVAL>616263646566</BINVAL>"
75 "</PHOTO>"
76 "<BDAY>1234</BDAY>"
77 "<MAILER>mutt</MAILER>"
78 "</vCard>";
79
80 CPPUNIT_ASSERT_EQUAL(expectedResult, testling.serialize(vcard));
81 }
82};
83
84CPPUNIT_TEST_SUITE_REGISTRATION(VCardSerializerTest);
diff --git a/Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp b/Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp
index 8975818..5953ef6 100644
--- a/Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp
+++ b/Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp
@@ -8,25 +8,32 @@
8 8
9#include <boost/shared_ptr.hpp> 9#include <boost/shared_ptr.hpp>
10 10
11#include "Swiften/Serializer/XML/XMLElement.h" 11#include "Swiften/Serializer/XML/XMLElement.h"
12#include "Swiften/Serializer/XML/XMLTextNode.h" 12#include "Swiften/Serializer/XML/XMLTextNode.h"
13#include "Swiften/Serializer/XML/XMLRawTextNode.h"
13#include "Swiften/StringCodecs/Hexify.h" 14#include "Swiften/StringCodecs/Hexify.h"
15#include "Swiften/Base/foreach.h"
14 16
15namespace Swift { 17namespace Swift {
16 18
17VCardSerializer::VCardSerializer() : GenericPayloadSerializer<VCard>() { 19VCardSerializer::VCardSerializer() : GenericPayloadSerializer<VCard>() {
18} 20}
19 21
20String VCardSerializer::serializePayload(boost::shared_ptr<VCard> vcard) const { 22String VCardSerializer::serializePayload(boost::shared_ptr<VCard> vcard) const {
21 XMLElement queryElement("vCard", "vcard-temp"); 23 XMLElement queryElement("vCard", "vcard-temp");
24 if (!vcard->getVersion().isEmpty()) {
25 boost::shared_ptr<XMLElement> versionElement(new XMLElement("VERSION"));
26 versionElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(vcard->getVersion())));
27 queryElement.addNode(versionElement);
28 }
22 if (!vcard->getFullName().isEmpty()) { 29 if (!vcard->getFullName().isEmpty()) {
23 boost::shared_ptr<XMLElement> fullNameElement(new XMLElement("FN")); 30 boost::shared_ptr<XMLElement> fullNameElement(new XMLElement("FN"));
24 fullNameElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(vcard->getFullName()))); 31 fullNameElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(vcard->getFullName())));
25 queryElement.addNode(fullNameElement); 32 queryElement.addNode(fullNameElement);
26 } 33 }
27 if (!vcard->getGivenName().isEmpty() || !vcard->getFamilyName().isEmpty()) { 34 if (!vcard->getGivenName().isEmpty() || !vcard->getFamilyName().isEmpty() || !vcard->getMiddleName().isEmpty() || !vcard->getPrefix().isEmpty() || !vcard->getSuffix().isEmpty()) {
28 boost::shared_ptr<XMLElement> nameElement(new XMLElement("N")); 35 boost::shared_ptr<XMLElement> nameElement(new XMLElement("N"));
29 if (!vcard->getFamilyName().isEmpty()) { 36 if (!vcard->getFamilyName().isEmpty()) {
30 boost::shared_ptr<XMLElement> familyNameElement(new XMLElement("FAMILY")); 37 boost::shared_ptr<XMLElement> familyNameElement(new XMLElement("FAMILY"));
31 familyNameElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(vcard->getFamilyName()))); 38 familyNameElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(vcard->getFamilyName())));
32 nameElement->addNode(familyNameElement); 39 nameElement->addNode(familyNameElement);
@@ -34,17 +41,47 @@ String VCardSerializer::serializePayload(boost::shared_ptr<VCard> vcard) const
34 if (!vcard->getGivenName().isEmpty()) { 41 if (!vcard->getGivenName().isEmpty()) {
35 boost::shared_ptr<XMLElement> givenNameElement(new XMLElement("GIVEN")); 42 boost::shared_ptr<XMLElement> givenNameElement(new XMLElement("GIVEN"));
36 givenNameElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(vcard->getGivenName()))); 43 givenNameElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(vcard->getGivenName())));
37 nameElement->addNode(givenNameElement); 44 nameElement->addNode(givenNameElement);
38 } 45 }
46 if (!vcard->getMiddleName().isEmpty()) {
47 boost::shared_ptr<XMLElement> middleNameElement(new XMLElement("MIDDLE"));
48 middleNameElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(vcard->getMiddleName())));
49 nameElement->addNode(middleNameElement);
50 }
51 if (!vcard->getPrefix().isEmpty()) {
52 boost::shared_ptr<XMLElement> prefixElement(new XMLElement("PREFIX"));
53 prefixElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(vcard->getPrefix())));
54 nameElement->addNode(prefixElement);
55 }
56 if (!vcard->getSuffix().isEmpty()) {
57 boost::shared_ptr<XMLElement> suffixElement(new XMLElement("SUFFIX"));
58 suffixElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(vcard->getSuffix())));
59 nameElement->addNode(suffixElement);
60 }
39 queryElement.addNode(nameElement); 61 queryElement.addNode(nameElement);
40 } 62 }
41 if (!vcard->getEMail().isEmpty()) { 63 foreach(const VCard::EMailAddress& emailAddress, vcard->getEMailAddresses()) {
42 boost::shared_ptr<XMLElement> emailElement(new XMLElement("EMAIL")); 64 boost::shared_ptr<XMLElement> emailElement(new XMLElement("EMAIL"));
43 boost::shared_ptr<XMLElement> userIDElement(new XMLElement("USERID")); 65 boost::shared_ptr<XMLElement> userIDElement(new XMLElement("USERID"));
44 userIDElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(vcard->getEMail()))); 66 userIDElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(emailAddress.address)));
45 emailElement->addNode(userIDElement); 67 emailElement->addNode(userIDElement);
68 if (emailAddress.isHome) {
69 emailElement->addNode(boost::shared_ptr<XMLElement>(new XMLElement("HOME")));
70 }
71 if (emailAddress.isWork) {
72 emailElement->addNode(boost::shared_ptr<XMLElement>(new XMLElement("WORK")));
73 }
74 if (emailAddress.isInternet) {
75 emailElement->addNode(boost::shared_ptr<XMLElement>(new XMLElement("INTERNET")));
76 }
77 if (emailAddress.isPreferred) {
78 emailElement->addNode(boost::shared_ptr<XMLElement>(new XMLElement("PREF")));
79 }
80 if (emailAddress.isX400) {
81 emailElement->addNode(boost::shared_ptr<XMLElement>(new XMLElement("X400")));
82 }
46 queryElement.addNode(emailElement); 83 queryElement.addNode(emailElement);
47 } 84 }
48 if (!vcard->getNickname().isEmpty()) { 85 if (!vcard->getNickname().isEmpty()) {
49 boost::shared_ptr<XMLElement> nickElement(new XMLElement("NICKNAME")); 86 boost::shared_ptr<XMLElement> nickElement(new XMLElement("NICKNAME"));
50 nickElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(vcard->getNickname()))); 87 nickElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(vcard->getNickname())));
@@ -62,9 +99,12 @@ String VCardSerializer::serializePayload(boost::shared_ptr<VCard> vcard) const
62 binvalElement->addNode(XMLTextNode::ref(new XMLTextNode(Hexify::hexify(vcard->getPhoto())))); 99 binvalElement->addNode(XMLTextNode::ref(new XMLTextNode(Hexify::hexify(vcard->getPhoto()))));
63 photoElement->addNode(binvalElement); 100 photoElement->addNode(binvalElement);
64 } 101 }
65 queryElement.addNode(photoElement); 102 queryElement.addNode(photoElement);
66 } 103 }
104 if (!vcard->getUnknownContent().isEmpty()) {
105 queryElement.addNode(boost::shared_ptr<XMLRawTextNode>(new XMLRawTextNode(vcard->getUnknownContent())));
106 }
67 return queryElement.serialize(); 107 return queryElement.serialize();
68} 108}
69 109
70} 110}