diff options
Diffstat (limited to 'Swiften')
| -rw-r--r-- | Swiften/Elements/VCard.cpp | 26 | ||||
| -rw-r--r-- | Swiften/Elements/VCard.h | 52 | ||||
| -rw-r--r-- | Swiften/Parser/PayloadParsers/RosterParser.cpp | 1 | ||||
| -rw-r--r-- | Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp | 59 | ||||
| -rw-r--r-- | Swiften/Parser/PayloadParsers/VCardParser.cpp | 87 | ||||
| -rw-r--r-- | Swiften/Parser/PayloadParsers/VCardParser.h | 2 | ||||
| -rw-r--r-- | Swiften/SConscript | 2 | ||||
| -rw-r--r-- | Swiften/Serializer/PayloadSerializers/UnitTest/VCardSerializerTest.cpp | 84 | ||||
| -rw-r--r-- | Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp | 46 |
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 | |||
| 11 | namespace Swift { | ||
| 12 | |||
| 13 | VCard::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 | ||
| 14 | namespace Swift { | 14 | namespace 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 | ||
| 13 | using namespace Swift; | 13 | using namespace Swift; |
| 14 | 14 | ||
| 15 | class VCardParserTest : public CppUnit::TestFixture | 15 | class 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 | ||
| 11 | namespace Swift { | 12 | namespace Swift { |
| 12 | 13 | ||
| 13 | VCardParser::VCardParser() { | 14 | VCardParser::VCardParser() : unknownContentParser_(NULL) { |
| 14 | } | 15 | } |
| 15 | 16 | ||
| 16 | void VCardParser::handleStartElement(const String& element, const String&, const AttributeMap&) { | 17 | void 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 | ||
| 21 | void VCardParser::handleEndElement(const String&, const String&) { | 35 | void 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 | ||
| 47 | void VCardParser::handleCharacterData(const String& text) { | 107 | void VCardParser::handleCharacterData(const String& text) { |
| 108 | if (unknownContentParser_) { | ||
| 109 | unknownContentParser_->handleCharacterData(text); | ||
| 110 | } | ||
| 48 | currentText_ += text; | 111 | currentText_ += text; |
| 49 | } | 112 | } |
| 50 | 113 | ||
| 51 | String VCardParser::getElementHierarchy() const { | 114 | String 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 | |||
| 12 | using namespace Swift; | ||
| 13 | |||
| 14 | class 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 | |||
| 84 | CPPUNIT_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 | ||
| 15 | namespace Swift { | 17 | namespace Swift { |
| 16 | 18 | ||
| 17 | VCardSerializer::VCardSerializer() : GenericPayloadSerializer<VCard>() { | 19 | VCardSerializer::VCardSerializer() : GenericPayloadSerializer<VCard>() { |
| 18 | } | 20 | } |
| 19 | 21 | ||
| 20 | String VCardSerializer::serializePayload(boost::shared_ptr<VCard> vcard) const { | 22 | String 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 | } |
Swift