3 commits - c++/lib c++/tests schemas/xCard.xsd
Christian Mollekopf
mollekopf at kolabsys.com
Thu Mar 8 10:29:30 CET 2012
c++/lib/kolabcontact.cpp | 6 ++---
c++/lib/kolabcontact.h | 27 ++++++++++++++++++++++---
c++/lib/utils.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++-
c++/lib/utils.h | 4 +++
c++/lib/xcalconversions.h | 12 +++++------
c++/lib/xcardconversions.h | 36 +++++++++++++++++++++++++++++-----
c++/tests/bindingstest.cpp | 12 ++++++++---
c++/tests/conversiontest.cpp | 30 ++++++++++++++++++++++++++++
c++/tests/conversiontest.h | 3 ++
c++/tests/serializers.h | 22 +++++++++++++++++++++
schemas/xCard.xsd | 28 +++++++++++++++++++++-----
11 files changed, 199 insertions(+), 26 deletions(-)
New commits:
commit 23ff54526debf8fba5e2d6cf59db972b75ac7c60
Merge: a8c894f e039d6d
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Thu Mar 8 10:02:35 2012 +0100
Merge branch 'master' of ssh://git.kolabsys.com/git/libkolabxml
diff --cc c++/tests/conversiontest.cpp
index f6775f0,0752c90..218ea42
--- a/c++/tests/conversiontest.cpp
+++ b/c++/tests/conversiontest.cpp
@@@ -10,9 -10,8 +10,9 @@@
Q_DECLARE_METATYPE(Kolab::Duration);
Q_DECLARE_METATYPE(Kolab::DayPos);
- Q_DECLARE_METATYPE(Kolab::KoDateTime);
+ Q_DECLARE_METATYPE(Kolab::cDateTime);
Q_DECLARE_METATYPE(Kolab::ErrorSeverity);
+Q_DECLARE_METATYPE(std::string);
using namespace Kolab::XCAL;
commit a8c894f26196638159f73e824bfa91517f52855d
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Thu Mar 8 10:02:25 2012 +0100
x-uid and mailto handling.
diff --git a/c++/lib/kolabcontact.cpp b/c++/lib/kolabcontact.cpp
index fc99d83..ce3e0e1 100644
--- a/c++/lib/kolabcontact.cpp
+++ b/c++/lib/kolabcontact.cpp
@@ -28,7 +28,7 @@ struct DistList::Private
std::vector< std::string > categories;
std::string name;
- std::vector<std::string> members;
+ std::vector<Member> members;
std::vector<CustomProperty> customProperties;
};
@@ -89,12 +89,12 @@ std::string DistList::name() const
return d->name;
}
-void DistList::setMembers(const std::vector< std::string > members)
+void DistList::setMembers(const std::vector< Member > &members)
{
d->members = members;
}
-std::vector< std::string > DistList::members() const
+std::vector< Member > DistList::members() const
{
return d->members;
}
diff --git a/c++/lib/kolabcontact.h b/c++/lib/kolabcontact.h
index 5c74f7e..a449851 100644
--- a/c++/lib/kolabcontact.h
+++ b/c++/lib/kolabcontact.h
@@ -182,7 +182,28 @@ struct Crypto {
};
-
+struct Member {
+ Member(){};
+ Member(const std::string &email): mEmail(email) {};
+ bool operator==(const Member &other) const { return mEmail == other.mEmail &&
+ mName == other.mName &&
+ mUid == mUid;
+ };
+
+ void setEmail(const std::string &email) { mEmail = email; };
+ std::string email() const { return mEmail; };
+
+ void setName(const std::string &name) { mName = name; };
+ std::string name() const { return mName; };
+
+ void setUid(const std::string &uid) { mUid = uid; };
+ std::string uid() const { return mUid; };
+
+private:
+ std::string mEmail;
+ std::string mName;
+ std::string mUid;
+};
class DistList {
public:
@@ -202,8 +223,8 @@ public:
void setName(const std::string &);
std::string name() const;
- void setMembers(const std::vector<std::string> members);
- std::vector<std::string> members() const;
+ void setMembers(const std::vector<Member> &);
+ std::vector<Member> members() const;
void setCustomProperties(const std::vector<CustomProperty> &);
std::vector<CustomProperty> customProperties() const;
diff --git a/c++/lib/utils.cpp b/c++/lib/utils.cpp
index da9c34f..269d8ce 100644
--- a/c++/lib/utils.cpp
+++ b/c++/lib/utils.cpp
@@ -183,6 +183,49 @@ std::string uriInlineDecoding(const std::string &s, std::string &mimetype)
return base64_decode(s.substr(pos+8, s.size()-(pos+8)));
}
+std::string toMailto(const std::string &email, const std::string &name)
+{
+ std::string mailto;
+ if (!name.empty()) {
+ mailto.append(name);
+ }
+ mailto.append("<");
+ mailto.append(email);
+ mailto.append(">");
+ return std::string("mailto:")+mailto;
+}
+
+std::string fromMailto(const std::string &mailtoUri, std::string &name)
+{
+ const std::string &decoded = mailtoUri;
+ if (decoded.substr(0, 7).compare("mailto:")) {
+ WARNING("no mailto address");
+ std::cout << decoded << std::endl;
+ return mailtoUri;
+ }
+ std::size_t begin = decoded.find('<',7);
+ if (begin == std::string::npos) {
+ WARNING("no mailto address");
+ std::cout << decoded << std::endl;
+ return mailtoUri;
+ }
+ std::size_t end = decoded.find('>', begin);
+ if (end == std::string::npos) {
+ WARNING("no mailto address");
+ std::cout << decoded << std::endl;
+ return mailtoUri;
+ }
+ name = decoded.substr(7, begin-7);
+ const std::string &email = decoded.substr(begin+1, end-begin-1);
+ return email;
+}
+
+std::string fromMailto(const std::string &mailtoUri)
+{
+ std::string n;
+ return fromMailto(mailtoUri, n);
+}
+
} //Namespace
} //Namespace
\ No newline at end of file
diff --git a/c++/lib/utils.h b/c++/lib/utils.h
index b7b69ea..55ed292 100644
--- a/c++/lib/utils.h
+++ b/c++/lib/utils.h
@@ -110,6 +110,10 @@ T fromInt(int integer)
std::string uriInlineEncoding(const std::string &, const std::string &mime);
std::string uriInlineDecoding(const std::string &s, std::string &mimetype);
+std::string toMailto(const std::string &email, const std::string &name = std::string());
+std::string fromMailto(const std::string &mailtoUri, std::string &name);
+std::string fromMailto(const std::string &mailtoUri);
+
} //Namespace
} //Namespace
diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index 932b000..ca54642 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -358,7 +358,7 @@ void setCalAddress(const icalendar_2_0::CalAddressPropertyType &cal, std::string
}
}
}
- email = cal.cal_address();
+ email = fromMailto(cal.cal_address());
}
@@ -877,7 +877,7 @@ void setIncidenceProperties(I &inc, const T &prop)
if (prop.attendee().size()) {
std::vector<Kolab::Attendee> attendees;
BOOST_FOREACH(typename T::attendee_type aProp, prop.attendee()) {
- Kolab::Attendee a(toString(aProp.cal_address()));
+ Kolab::Attendee a(fromMailto(toString(aProp.cal_address())));
if (aProp.parameters()) {
const icalendar_2_0::AttendeePropType::parameters_type ¶meters = *aProp.parameters();
for (icalendar_2_0::AttendeePropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
@@ -1130,7 +1130,7 @@ void getIncidenceProperties(T &prop, const I &inc)
if (!inc.attendees().empty()) {
BOOST_FOREACH(const Kolab::Attendee &a, inc.attendees()) {
- typename properties::attendee_type attendee(a.email());
+ typename properties::attendee_type attendee(toMailto(a.email()));
typename properties::attendee_type::parameters_type p;
if (!a.name().empty()) {
@@ -1220,7 +1220,7 @@ void getTodoEventProperties(T &prop, const I &inc)
}
if (!inc.organizerEmail().empty()) { //email is required
- typename properties::organizer_type organizer(inc.organizerEmail());
+ typename properties::organizer_type organizer(toMailto(inc.organizerEmail()));
typename properties::organizer_type::parameters_type p; //There is maybe already a timezone set
icalendar_2_0::CnParamType name(inc.organizerName());
@@ -1269,7 +1269,7 @@ void setAlarms(typename KolabType::components_type& components, const IncidenceT
p->summary(PropType::summary_type(alarm.summary()));
p->description(PropType::description_type(alarm.description()));
BOOST_FOREACH(const std::string &attendee, alarm.attendees()) {
- p->attendee().push_back(icalendar_2_0::ContactType(attendee));
+ p->attendee().push_back(icalendar_2_0::ContactType(toMailto(attendee)));
}
break;
case Kolab::Alarm::AudioAlarm:
@@ -1310,7 +1310,7 @@ void getAlarms(IncidenceType &incidence, const typename KolabType::components_ty
} else if (prop.action().text() == EMAILALARM) {
std::vector<std::string> attendees;
for (typename PropType::attendee_const_iterator at(prop.attendee().begin()); at != prop.attendee().end(); at++) {
- attendees.push_back((*at).cal_address());
+ attendees.push_back(fromMailto((*at).cal_address()));
}
if (!prop.description() || !prop.summary()) {
ERROR("description or summary is missing");
diff --git a/c++/lib/xcardconversions.h b/c++/lib/xcardconversions.h
index f406105..d8d7ba4 100644
--- a/c++/lib/xcardconversions.h
+++ b/c++/lib/xcardconversions.h
@@ -461,7 +461,17 @@ template <>
void writeCard<Kolab::DistList>(vcard_4_0::vcard &vcard, const Kolab::DistList &distlist)
{
if (!distlist.members().empty()) {
- vcard.member(fromList<vcard_4_0::vcard::member_type>(distlist.members()));
+ vcard_4_0::vcard::member_sequence members;
+ BOOST_FOREACH (const Kolab::Member &m, distlist.members()) {
+ vcard_4_0::vcard::member_type member(toMailto(m.email(), m.name()));
+ if (!m.uid().empty()) {
+ vcard_4_0::ArrayOfParameters parameters;
+ parameters.baseParameter().push_back(vcard_4_0::xuidParamType(m.uid()));
+ member.parameters(parameters);
+ }
+ members.push_back(member);
+ }
+ vcard.member(members);
} else {
WARNING("empty distlist");
}
@@ -748,9 +758,25 @@ boost::shared_ptr<Kolab::DistList> readCard <Kolab::DistList> (const vcard_4_0::
{
using namespace vcard_4_0;
boost::shared_ptr<Kolab::DistList> distlist(new Kolab::DistList);
-
+
if (!vcard.member().empty()) {
- distlist->setMembers(toUriList<vcard_4_0::vcard::member_type>(vcard.member()));
+ std::vector<Kolab::Member> members;
+
+ BOOST_FOREACH(const vcard_4_0::vcard::member_type & m, vcard.member()) {
+ std::string name;
+ std::string email = fromMailto(m.uri(), name);
+ Kolab::Member member(email);
+ member.setName(name);
+ if (m.parameters()) {
+ BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type ¶m, (*m.parameters()).baseParameter()) {
+ if (const vcard_4_0::xuidParamType *uid = dynamic_cast<const vcard_4_0::xuidParamType*> (¶m)) {
+ member.setUid(uid->uri());
+ }
+ }
+ }
+ members.push_back(member);
+ }
+ distlist->setMembers(members);
} else {
WARNING("empty distlist");
}
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 2ed8882..486c250 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -316,7 +316,7 @@ void BindingsTest::contactCompletness()
stringlist.push_back("sdf");
Kolab::Contact c;
- c.setUid("uid");
+ c.setUid("urn:uuid:1045b57d-ff7f-0000-d814-867b4d7f0000");
c.setCategories(stringlist);
c.setName("name");
Kolab::NameComponents nc;
@@ -431,7 +431,13 @@ void BindingsTest::distlistCompletness()
Kolab::DistList c;
c.setName("name");
c.setUid("uid");
- c.setMembers(stringlist);
+ std::vector<Kolab::Member> members;
+ members.push_back(Kolab::Member("email at email.com"));
+ Kolab::Member m2("email2 at email.com");
+ m2.setName("name todo");
+ m2.setUid("uid");
+ members.push_back(m2);
+ c.setMembers(members);
std::vector<Kolab::CustomProperty> properties;
properties.push_back(Kolab::CustomProperty("ident", "value"));
properties.push_back(Kolab::CustomProperty("ident", "value"));
@@ -439,7 +445,7 @@ void BindingsTest::distlistCompletness()
const std::string result = Kolab::writeDistlist(c);
QVERIFY(Kolab::error() == Kolab::NoError);
-// std::cout << result << endl;
+ std::cout << result << endl;
Kolab::DistList e = Kolab::readDistlist(result, false);
QVERIFY(Kolab::error() == Kolab::NoError);
QCOMPARE(e.uid(), c.uid());
diff --git a/c++/tests/conversiontest.cpp b/c++/tests/conversiontest.cpp
index bc2ebcc..f6775f0 100644
--- a/c++/tests/conversiontest.cpp
+++ b/c++/tests/conversiontest.cpp
@@ -12,6 +12,7 @@ Q_DECLARE_METATYPE(Kolab::Duration);
Q_DECLARE_METATYPE(Kolab::DayPos);
Q_DECLARE_METATYPE(Kolab::KoDateTime);
Q_DECLARE_METATYPE(Kolab::ErrorSeverity);
+Q_DECLARE_METATYPE(std::string);
using namespace Kolab::XCAL;
@@ -169,6 +170,35 @@ void ConversionTest::uriInlineEncodingTest()
QCOMPARE(Kolab::Utils::getError(), Kolab::NoError);
}
+void ConversionTest::mailtoUriEncodingTest_data()
+{
+ QTest::addColumn<QString>("email");
+ QTest::addColumn<QString>("name");
+ QTest::addColumn<QString>("result");
+ QTest::addColumn<QString>("resultEncoded");
+
+ QTest::newRow("1") << "email_1 at email.com" << "John Doe" << "mailto:John Doe<email_1 at email.com>" << "mailto:John%20Doe%3Cemail%5F1%40email%2Ecom%3E";
+
+ Kolab::Utils::clearErrors();
+}
+
+void ConversionTest::mailtoUriEncodingTest()
+{
+ QFETCH(QString, email);
+ QFETCH(QString, name);
+ QFETCH(QString, result);
+ QFETCH(QString, resultEncoded);
+ const std::string &mailto = Kolab::XCARD::toMailto(email.toStdString(), name.toStdString());
+ std::cout << mailto << std::endl;
+ QCOMPARE(QString::fromStdString(mailto), resultEncoded);
+ std::string n;
+ const std::string &e = Kolab::XCARD::fromMailto(mailto, n);
+ QCOMPARE(QString::fromStdString(n), name);
+ QCOMPARE(QString::fromStdString(e), email);
+
+}
+
+
void threadF()
{
for (int i = 0; i < 5; ++i)
diff --git a/c++/tests/conversiontest.h b/c++/tests/conversiontest.h
index e99bf0c..3ccdd1c 100644
--- a/c++/tests/conversiontest.h
+++ b/c++/tests/conversiontest.h
@@ -30,6 +30,9 @@ class ConversionTest : public QObject
void uriInlineEncodingTest();
+ void mailtoUriEncodingTest_data();
+ void mailtoUriEncodingTest();
+
void threadLocalTest();
};
diff --git a/c++/tests/serializers.h b/c++/tests/serializers.h
index c92f577..6a0af74 100644
--- a/c++/tests/serializers.h
+++ b/c++/tests/serializers.h
@@ -164,6 +164,28 @@ namespace QTest {
ba += ")";
return qstrdup(ba.data());
}
+
+ template<>
+ char *toString(const Kolab::Member &a)
+ {
+ QByteArray ba = "Kolab::Member(";
+ ba += QString::fromStdString(a.email()).toAscii()+ ", ";
+ ba += QString::fromStdString(a.name()).toAscii()+ ", ";
+ ba += QString::fromStdString(a.uid()).toAscii();
+ ba += ")";
+ return qstrdup(ba.data());
+ }
+
+ template<>
+ char *toString(const std::vector<Kolab::Member> &v)
+ {
+ QByteArray ba = "vector<Kolab::Member>(";
+ for (int i = 0; i < v.size(); i++) {
+ ba += QByteArray(toString(v.at(i)))+ "\n";
+ }
+ ba += ")";
+ return qstrdup(ba.data());
+ }
}
diff --git a/schemas/xCard.xsd b/schemas/xCard.xsd
index 89d7481..429e4bf 100644
--- a/schemas/xCard.xsd
+++ b/schemas/xCard.xsd
@@ -50,11 +50,17 @@
</xs:extension>
</xs:complexContent>
</xs:complexType>
+
+ <xs:complexType name="UriParameterType" mixed="false">
+ <xs:complexContent>
+ <xs:extension base="xcard:BaseParameterType">
+ <xs:sequence>
+ <xs:element ref="xcard:uri"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
- <!-- WARNING: don't forget to add those, otherwise the serialization code will not be built and you're up for a long debugging session -->
- <xs:element name="type" type="xcard:typeParamType" substitutionGroup="xcard:baseParameter"/>
- <xs:element name="label" type="xcard:labelParamType" substitutionGroup="xcard:baseParameter"/>
- <xs:element name="pref" type="xcard:prefParamType" substitutionGroup="xcard:baseParameter"/>
<xs:simpleType name="TypeValueType">
<xs:restriction base="xs:token">
@@ -96,7 +102,19 @@
</xs:extension>
</xs:complexContent>
</xs:complexType>
+
+ <xs:complexType name="xuidParamType" mixed="false">
+ <xs:complexContent>
+ <xs:extension base="xcard:UriParameterType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <!-- WARNING: don't forget to add those, otherwise the serialization code will not be built and you're up for a long debugging session -->
+ <xs:element name="type" type="xcard:typeParamType" substitutionGroup="xcard:baseParameter"/>
+ <xs:element name="label" type="xcard:labelParamType" substitutionGroup="xcard:baseParameter"/>
+ <xs:element name="pref" type="xcard:prefParamType" substitutionGroup="xcard:baseParameter"/>
+ <xs:element name="x-uid" type="xcard:xuidParamType" substitutionGroup="xcard:baseParameter"/>
+
<!-- Properties -->
<xs:complexType name="BasePropertyType" abstract="true" >
<xs:sequence>
commit 039c548357d435350958569d5e32be0a96d4759b
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Wed Mar 7 18:08:55 2012 +0100
xcard uid is a uri.
diff --git a/c++/lib/utils.cpp b/c++/lib/utils.cpp
index d476dfd..da9c34f 100644
--- a/c++/lib/utils.cpp
+++ b/c++/lib/utils.cpp
@@ -93,7 +93,7 @@ std::string getUID(const std::string &s)
{
if (s.empty()) {
boost::uuids::uuid u; // initialize uuid
- return boost::uuids::to_string(u);
+ return std::string("urn:uuid:")+boost::uuids::to_string(u);
}
return s;
}
diff --git a/c++/lib/xcardconversions.h b/c++/lib/xcardconversions.h
index 5f7bbe8..f406105 100644
--- a/c++/lib/xcardconversions.h
+++ b/c++/lib/xcardconversions.h
@@ -478,7 +478,7 @@ std::string serializeCard(const T &card, const std::string prod = std::string())
try {
vcard_4_0::vcard::uid_type uid(getUID(card.uid()));
- setCreatedUid(uid.text());
+ setCreatedUid(uid.uri());
vcard_4_0::vcard::x_kolab_version_type kolab_version(KOLAB_FORMAT_VERSION);
vcard_4_0::vcard::prodid_type prodid(prod+KOLAB_LIBNAME+KOLAB_LIB_VERSION);
vcard_4_0::vcard::rev_type rev(fromDateTime(getCurrentTime()));
@@ -781,7 +781,7 @@ boost::shared_ptr<T> deserializeCard(const std::string& s, bool isUrl)
}
boost::shared_ptr<T> card = readCard<T>(vcards->vcard());
- card->setUid(vcards->vcard().uid().text());
+ card->setUid(vcards->vcard().uid().uri());
card->setName(vcards->vcard().fn().text());
setProductId( vcards->vcard().prodid().text() );
diff --git a/schemas/xCard.xsd b/schemas/xCard.xsd
index 1d23de6..89d7481 100644
--- a/schemas/xCard.xsd
+++ b/schemas/xCard.xsd
@@ -225,7 +225,7 @@
<xs:complexType name="uidPropType">
<xs:complexContent mixed="false">
- <xs:extension base="xcard:TextPropertyType"/>
+ <xs:extension base="xcard:UriPropertyType"/>
</xs:complexContent>
</xs:complexType>
More information about the commits
mailing list