Commit 97024aad authored by Sylvain Berfini's avatar Sylvain Berfini 🎩

Added Email, IMPP and Lang properties

parent e17db229
......@@ -28,6 +28,9 @@ namespace belcard {
list<shared_ptr<BelCardPhoto>> _photos;
list<shared_ptr<BelCardAddress>> _addr;
list<shared_ptr<BelCardTel>> _tel;
list<shared_ptr<BelCardEmail>> _emails;
list<shared_ptr<BelCardImpp>> _impp;
list<shared_ptr<BelCardLang>> _langs;
list<shared_ptr<BelCardProperty>> _properties;
public:
......@@ -46,7 +49,10 @@ namespace belcard {
->setCollector("NICKNAME", make_sfn(&BelCard::addNickname))
->setCollector("PHOTO", make_sfn(&BelCard::addPhoto))
->setCollector("ADR", make_sfn(&BelCard::addAddress))
->setCollector("TEL", make_sfn(&BelCard::addTel));
->setCollector("TEL", make_sfn(&BelCard::addTel))
->setCollector("EMAIL", make_sfn(&BelCard::addEmail))
->setCollector("IMPP", make_sfn(&BelCard::addImpp))
->setCollector("LANG", make_sfn(&BelCard::addLang));
}
BelCard() {
......@@ -133,6 +139,30 @@ namespace belcard {
return _tel;
}
void addEmail(const shared_ptr<BelCardEmail> &email) {
_emails.push_back(email);
addProperty(email);
}
const list<shared_ptr<BelCardEmail>> &getEmails() const {
return _emails;
}
void addImpp(const shared_ptr<BelCardImpp> &impp) {
_impp.push_back(impp);
addProperty(impp);
}
const list<shared_ptr<BelCardImpp>> &getImpp() const {
return _impp;
}
void addLang(const shared_ptr<BelCardLang> &lang) {
_langs.push_back(lang);
addProperty(lang);
}
const list<shared_ptr<BelCardLang>> &getLangs() const {
return _langs;
}
void addProperty(const shared_ptr<BelCardProperty> &property) {
_properties.push_back(property);
}
......
......@@ -43,6 +43,102 @@ namespace belcard {
BelCardProperty::addParam(param);
}
};
class BelCardEmail : public BelCardProperty {
public:
static shared_ptr<BelCardEmail> create() {
return make_shared<BelCardEmail>();
}
static shared_ptr<BelCardEmail> parse(const string& input) {
ABNFGrammarBuilder grammar_builder;
shared_ptr<Grammar> grammar = grammar_builder.createFromAbnf((const char*)vcard_grammar, make_shared<CoreRules>());
Parser<shared_ptr<BelCardGeneric>> parser(grammar);
setHandlerAndCollectors(&parser);
BelCardParam::setHandlerAndCollectors(&parser);
shared_ptr<BelCardGeneric> ret = parser.parseInput("EMAIL", input, NULL);
return dynamic_pointer_cast<BelCardEmail>(ret);
}
static void setHandlerAndCollectors(Parser<shared_ptr<BelCardGeneric>> *parser) {
parser->setHandler("EMAIL", make_fn(&BelCardEmail::create))
->setCollector("group", make_sfn(&BelCardEmail::setGroup))
->setCollector("any-param", make_sfn(&BelCardEmail::addParam))
->setCollector("EMAIL-value", make_sfn(&BelCardEmail::setValue));
}
BelCardEmail() : BelCardProperty() {
setName("EMAIL");
}
virtual void addParam(const shared_ptr<BelCardParam> &param) {
BelCardProperty::addParam(param);
}
};
class BelCardImpp : public BelCardProperty {
public:
static shared_ptr<BelCardImpp> create() {
return make_shared<BelCardImpp>();
}
static shared_ptr<BelCardImpp> parse(const string& input) {
ABNFGrammarBuilder grammar_builder;
shared_ptr<Grammar> grammar = grammar_builder.createFromAbnf((const char*)vcard_grammar, make_shared<CoreRules>());
Parser<shared_ptr<BelCardGeneric>> parser(grammar);
setHandlerAndCollectors(&parser);
BelCardParam::setHandlerAndCollectors(&parser);
shared_ptr<BelCardGeneric> ret = parser.parseInput("IMPP", input, NULL);
return dynamic_pointer_cast<BelCardImpp>(ret);
}
static void setHandlerAndCollectors(Parser<shared_ptr<BelCardGeneric>> *parser) {
parser->setHandler("IMPP", make_fn(&BelCardImpp::create))
->setCollector("group", make_sfn(&BelCardImpp::setGroup))
->setCollector("any-param", make_sfn(&BelCardImpp::addParam))
->setCollector("IMPP-value", make_sfn(&BelCardImpp::setValue));
}
BelCardImpp() : BelCardProperty() {
setName("IMPP");
}
virtual void addParam(const shared_ptr<BelCardParam> &param) {
BelCardProperty::addParam(param);
}
};
class BelCardLang : public BelCardProperty {
public:
static shared_ptr<BelCardLang> create() {
return make_shared<BelCardLang>();
}
static shared_ptr<BelCardLang> parse(const string& input) {
ABNFGrammarBuilder grammar_builder;
shared_ptr<Grammar> grammar = grammar_builder.createFromAbnf((const char*)vcard_grammar, make_shared<CoreRules>());
Parser<shared_ptr<BelCardGeneric>> parser(grammar);
setHandlerAndCollectors(&parser);
BelCardParam::setHandlerAndCollectors(&parser);
shared_ptr<BelCardGeneric> ret = parser.parseInput("LANG", input, NULL);
return dynamic_pointer_cast<BelCardLang>(ret);
}
static void setHandlerAndCollectors(Parser<shared_ptr<BelCardGeneric>> *parser) {
parser->setHandler("LANG", make_fn(&BelCardLang::create))
->setCollector("group", make_sfn(&BelCardLang::setGroup))
->setCollector("any-param", make_sfn(&BelCardLang::addParam))
->setCollector("LANG-value", make_sfn(&BelCardLang::setValue));
}
BelCardLang() : BelCardProperty() {
setName("LANG");
}
virtual void addParam(const shared_ptr<BelCardParam> &param) {
BelCardProperty::addParam(param);
}
};
}
#endif
\ No newline at end of file
......@@ -30,6 +30,9 @@ shared_ptr<BelCard> BelCardParser::parse(const string &input) {
BelCardPhoto::setHandlerAndCollectors(&parser);
BelCardAddress::setHandlerAndCollectors(&parser);
BelCardTel::setHandlerAndCollectors(&parser);
BelCardEmail::setHandlerAndCollectors(&parser);
BelCardImpp::setHandlerAndCollectors(&parser);
BelCardLang::setHandlerAndCollectors(&parser);
size_t parsedSize = 0;
shared_ptr<BelCardGeneric> ret = parser.parseInput("vcard", vcard, &parsedSize);
......
......@@ -5,7 +5,8 @@ vcard = "BEGIN:VCARD" CRLF
1*property
"END:VCARD" CRLF
property = KIND / FN / N / NICKNAME / BDAY / ANNIVERSARY / GENDER / PHOTO / ADR / TEL
property = KIND / FN / N / NICKNAME / BDAY / ANNIVERSARY / GENDER / PHOTO
/ ADR / TEL / EMAIL / IMPP / LANG
KIND = [group "."] "KIND" *(";" any-param) ":" KIND-value CRLF
KIND-value = "individual" / "group" / "org" / "location" / iana-token / x-name
......@@ -52,6 +53,15 @@ ADR-country = component *("," component)
TEL = [group "."] "TEL" *(";" any-param) ":" TEL-value CRLF
TEL-value = URI / text
EMAIL = [group "."] "EMAIL" *(";" any-param) ":" EMAIL-value CRLF
EMAIL-value = text
IMPP = [group "."] "IMPP" *(";" any-param) ":" IMPP-value CRLF
IMPP-value = text
LANG = [group "."] "LANG" *(";" any-param) ":" LANG-value CRLF
LANG-value = Language-Tag
group = 1*(ALPHA / DIGIT / "-")
......@@ -205,3 +215,73 @@ reserved = gen-delims / sub-delims
gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="
Language-Tag = langtag ; normal language tags
/ privateuse ; private use tag
/ grandfathered ; grandfathered tags
langtag = language
["-" script]
["-" region]
*("-" variant)
*("-" extension)
["-" privateuse]
language = 2*3ALPHA ; shortest ISO 639 code
["-" extlang] ; sometimes followed by extended language subtags
/ 4ALPHA ; or reserved for future use
/ 5*8ALPHA ; or registered language subtag
extlang = 3ALPHA ; selected ISO 639 codes
*2("-" 3ALPHA) ; permanently reserved
script = 4ALPHA ; ISO 15924 code
region = 2ALPHA ; ISO 3166-1 code
/ 3DIGIT ; UN M.49 code
variant = 5*8alphanum ; registered variants
/ (DIGIT 3alphanum)
extension = singleton 1*("-" (2*8alphanum))
singleton = DIGIT ; 0 - 9
/ %x41-57 ; A - W
/ %x59-5A ; Y - Z
/ %x61-77 ; a - w
/ %x79-7A ; y - z
privateuse = "x" 1*("-" (1*8alphanum))
grandfathered = irregular ; non-redundant tags registered
/ regular ; during the RFC 3066 era
irregular = "en-GB-oed" ; irregular tags do not match
/ "i-ami" ; the 'langtag' production and
/ "i-bnn" ; would not otherwise be
/ "i-default" ; considered 'well-formed'
/ "i-enochian" ; These tags are all valid,
/ "i-hak" ; but most are deprecated
/ "i-klingon" ; in favor of more modern
/ "i-lux" ; subtags or subtag
/ "i-mingo" ; combination
/ "i-navajo"
/ "i-pwn"
/ "i-tao"
/ "i-tay"
/ "i-tsu"
/ "sgn-BE-FR"
/ "sgn-BE-NL"
/ "sgn-CH-DE"
regular = "art-lojban" ; these tags match the 'langtag'
/ "cel-gaulish" ; production, but their subtags
/ "no-bok" ; are not extended language
/ "no-nyn" ; or variant subtags: their meaning
/ "zh-guoyu" ; is defined by their registration
/ "zh-hakka" ; and all of these are deprecated
/ "zh-min" ; in favor of a more modern
/ "zh-min-nan" ; subtag or sequence of subtags
/ "zh-xiang"
alphanum = (ALPHA / DIGIT) ; letters and numbers
......@@ -13,10 +13,64 @@ static void tel_property(void) {
stringstream sstream;
sstream << *tel;
BC_ASSERT_EQUAL(input.compare(sstream.str()), 0, int, "%d");
input = "TEL;VALUE=uri;TYPE=\"voice,work\":tel:+33952636505\r\n";
tel = BelCardTel::parse(input);
BC_ASSERT_TRUE_FATAL(tel != NULL);
sstream.clear();
sstream.str(std::string());
sstream << *tel;
BC_ASSERT_EQUAL(input.compare(sstream.str()), 0, int, "%d");
input = "TEL;VALUE=text;TYPE=work:+33 9 52 63 65 05\r\n";
tel = BelCardTel::parse(input);
BC_ASSERT_TRUE_FATAL(tel != NULL);
sstream.clear();
sstream.str(std::string());
sstream << *tel;
BC_ASSERT_EQUAL(input.compare(sstream.str()), 0, int, "%d");
}
static void email_property(void) {
string input = "EMAIL;TYPE=work:sylvain.berfini@belledonne-communications.com\r\n";
shared_ptr<BelCardEmail> email = BelCardEmail::parse(input);
BC_ASSERT_TRUE_FATAL(email != NULL);
stringstream sstream;
sstream << *email;
BC_ASSERT_EQUAL(input.compare(sstream.str()), 0, int, "%d");
}
static void impp_property(void) {
string input = "IMPP;TYPE=work:sip:sylvain@sip.linphone.org\r\n";
shared_ptr<BelCardImpp> impp = BelCardImpp::parse(input);
BC_ASSERT_TRUE_FATAL(impp != NULL);
stringstream sstream;
sstream << *impp;
BC_ASSERT_EQUAL(input.compare(sstream.str()), 0, int, "%d");
}
static void lang_property(void) {
string input = "LANG;TYPE=home:fr\r\n";
shared_ptr<BelCardLang> lang = BelCardLang::parse(input);
BC_ASSERT_TRUE_FATAL(lang != NULL);
stringstream sstream;
sstream << *lang;
BC_ASSERT_EQUAL(input.compare(sstream.str()), 0, int, "%d");
input = "LANG:fr-FR\r\n";
lang = BelCardLang::parse(input);
BC_ASSERT_TRUE_FATAL(lang != NULL);
sstream.clear();
sstream.str(std::string());
sstream << *lang;
BC_ASSERT_EQUAL(input.compare(sstream.str()), 0, int, "%d");
}
static test_t tests[] = {
{ "Tel", tel_property },
{ "Email", email_property },
{ "IMPP", impp_property },
{ "Language", lang_property },
};
test_suite_t vcard_communication_properties_test_suite = {
......
This diff was suppressed by a .gitattributes entry.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment