Commit 4c6268bf authored by Sylvain Berfini's avatar Sylvain Berfini 🎩

Added fold/unfold (+ testers) and more properties

parent e7712026
......@@ -29,3 +29,5 @@ config.h
*.orig
belcard.kdev4
tests/belcard-tester
tests/belcard-folder
tests/belcard-unfolder
......@@ -16,6 +16,9 @@ namespace belcard {
private:
shared_ptr<BelCardFN> _fn;
shared_ptr<BelCardN> _n;
shared_ptr<BelCardBirthday> _bday;
shared_ptr<BelCardAnniversary> _anniversary;
shared_ptr<BelCardGender> _gender;
list<shared_ptr<BelCardNickname>> _nicknames;
list<shared_ptr<BelCardProperty>> _properties;
......@@ -44,6 +47,30 @@ namespace belcard {
return _n;
}
void setBirthday(const shared_ptr<BelCardBirthday> &bday) {
_bday = bday;
addProperty(_bday);
}
const shared_ptr<BelCardBirthday> &getBirthday() const {
return _bday;
}
void setAnniversary(const shared_ptr<BelCardAnniversary> &anniversary) {
_anniversary = anniversary;
addProperty(_anniversary);
}
const shared_ptr<BelCardAnniversary> &getAnniversary() const {
return _anniversary;
}
void setGender(const shared_ptr<BelCardGender> &gender) {
_gender = gender;
addProperty(_gender);
}
const shared_ptr<BelCardGender> &getGender() const {
return _gender;
}
void addNickname(const shared_ptr<BelCardNickname> &nickname) {
_nicknames.push_back(nickname);
addProperty(nickname);
......
......@@ -101,6 +101,51 @@ namespace belcard {
BelCardProperty::addParam(param);
}
};
class BelCardBirthday : public BelCardProperty {
public:
static shared_ptr<BelCardBirthday> create() {
return make_shared<BelCardBirthday>();
}
BelCardBirthday() : BelCardProperty() {
setName("BDAY");
}
virtual void addParam(const shared_ptr<BelCardParam> &param) {
BelCardProperty::addParam(param);
}
};
class BelCardAnniversary : public BelCardProperty {
public:
static shared_ptr<BelCardAnniversary> create() {
return make_shared<BelCardAnniversary>();
}
BelCardAnniversary() : BelCardProperty() {
setName("ANNIVERSARY");
}
virtual void addParam(const shared_ptr<BelCardParam> &param) {
BelCardProperty::addParam(param);
}
};
class BelCardGender : public BelCardProperty {
public:
static shared_ptr<BelCardGender> create() {
return make_shared<BelCardGender>();
}
BelCardGender() : BelCardProperty() {
setName("GENDER");
}
virtual void addParam(const shared_ptr<BelCardParam> &param) {
BelCardProperty::addParam(param);
}
};
}
#endif
\ No newline at end of file
......@@ -6,7 +6,9 @@
#include <belr/grammarbuilder.hh>
#include <belr/abnf.hh>
namespace belr {
using namespace::belr;
namespace belcard {
class BelCardParser {
private:
ABNFGrammarBuilder _grammar_builder;
......@@ -15,7 +17,12 @@ namespace belr {
public:
BelCardParser();
~BelCardParser();
shared_ptr<belcard::BelCard> parse(const string &input);
shared_ptr<BelCard> parse(const string &input);
string dumpVCard(const shared_ptr<BelCard> &card);
string fold(string input);
string unfold(string input);
};
}
......
......@@ -11,11 +11,20 @@ BelCardParser::BelCardParser() {
_grammar = _grammar_builder.createFromAbnf("vcardgrammar.txt", make_shared<CoreRules>());
}
BelCardParser::~BelCardParser() {
}
shared_ptr<BelCard> BelCardParser::parse(const string &input) {
unfold(input);
Parser<shared_ptr<BelCardGeneric>> parser(_grammar);
parser.setHandler("vcard", make_fn(&BelCard::create))
->setCollector("FN", make_sfn(&BelCard::setFN))
->setCollector("N", make_sfn(&BelCard::setN))
->setCollector("BDAY", make_sfn(&BelCard::setBirthday))
->setCollector("ANNIVERSARY", make_sfn(&BelCard::setAnniversary))
->setCollector("GENDER", make_sfn(&BelCard::setGender))
->setCollector("NICKNAME", make_sfn(&BelCard::addNickname));
parser.setHandler("any-param", make_fn(&BelCardParam::create))
......@@ -36,6 +45,21 @@ shared_ptr<BelCard> BelCardParser::parse(const string &input) {
->setCollector("N-prefixes", make_sfn(&BelCardN::setPrefixes))
->setCollector("N-suffixes", make_sfn(&BelCardN::setSuffixes));
parser.setHandler("BDAY", make_fn(&BelCardBirthday::create))
->setCollector("group", make_sfn(&BelCardBirthday::setGroup))
->setCollector("any-param", make_sfn(&BelCardBirthday::addParam))
->setCollector("BDAY-value", make_sfn(&BelCardBirthday::setValue));
parser.setHandler("ANNIVERSARY", make_fn(&BelCardAnniversary::create))
->setCollector("group", make_sfn(&BelCardAnniversary::setGroup))
->setCollector("any-param", make_sfn(&BelCardAnniversary::addParam))
->setCollector("ANNIVERSARY-value", make_sfn(&BelCardAnniversary::setValue));
parser.setHandler("GENDER", make_fn(&BelCardGender::create))
->setCollector("group", make_sfn(&BelCardGender::setGroup))
->setCollector("any-param", make_sfn(&BelCardGender::addParam))
->setCollector("GENDER-value", make_sfn(&BelCardGender::setValue));
parser.setHandler("NICKNAME", make_fn(&BelCardNickname::create))
->setCollector("group", make_sfn(&BelCardNickname::setGroup))
->setCollector("any-param", make_sfn(&BelCardNickname::addParam))
......@@ -45,4 +69,44 @@ shared_ptr<BelCard> BelCardParser::parse(const string &input) {
shared_ptr<BelCardGeneric> ret = parser.parseInput("vcard", input, &parsedSize);
shared_ptr<BelCard> belCard = dynamic_pointer_cast<BelCard>(ret);
return belCard;
}
string BelCardParser::dumpVCard(const shared_ptr<BelCard> &card) {
string output = card->toString();
return fold(output);
}
string BelCardParser::fold(string input) {
size_t crlf = 0;
size_t next_crlf = 0;
while (next_crlf != string::npos) {
next_crlf = input.find("\r\n", crlf);
if (next_crlf != string::npos) {
if (next_crlf - crlf > 77) {
input.insert(crlf + 77, "\r\n ");
crlf += 80;
} else {
crlf = next_crlf + 2;
}
}
}
return input;
}
string BelCardParser::unfold(string input) {
size_t crlf = input.find("\r\n");
while (crlf != string::npos) {
if (isspace(input[crlf + 2])) {
input.erase(crlf, 3);
} else {
crlf += 2;
}
crlf = input.find("\r\n", crlf);
}
return input;
}
\ No newline at end of file
bin_PROGRAMS=belcard-folder belcard-unfolder
noinst_PROGRAMS=belcard-tester
belcard_tester_SOURCES=belcard-tester.cpp
belcard_tester_LDADD=$(top_builddir)/src/libbelcard.la -lbelr
belcard_folder_SOURCES=belcard-folder.cpp
belcard_folder_LDADD=$(top_builddir)/src/libbelcard.la -lbelr
belcard_unfolder_SOURCES=belcard-unfolder.cpp
belcard_unfolder_LDADD=$(top_builddir)/src/libbelcard.la -lbelr
EXTRA_DIST=vcardgrammar.txt vcardtest.vcf
AM_CPPFLAGS=-I$(top_srcdir)/include
#include "belcard/belcard_parser.hpp"
#include <iostream>
#include <fstream>
#include <sstream>
using namespace::belr;
using namespace::belcard;
int main(int argc, char *argv[]) {
const char *file = NULL;
if (argc < 2) {
cerr << argv[0] << " <file to fold> - fold the content of a file" << endl;
return -1;
}
file = argv[1];
ifstream istr(file);
if (!istr.is_open()) {
return -1;
}
stringstream vcardStream;
vcardStream << istr.rdbuf();
string vcard = vcardStream.str();
BelCardParser *parser = new BelCardParser();
vcard = parser->fold(vcard);
cout << vcard << endl;
delete parser;
return 0;
}
\ No newline at end of file
......@@ -26,5 +26,6 @@ int main(int argc, char *argv[]) {
cerr << "Error: returned pointer is null" << endl;
}
delete parser;
return 0;
}
\ No newline at end of file
#include "belcard/belcard_parser.hpp"
#include <iostream>
#include <fstream>
#include <sstream>
using namespace::belr;
using namespace::belcard;
int main(int argc, char *argv[]) {
const char *file = NULL;
if (argc < 2) {
cerr << argv[0] << " <file to unfold> - unfold the content of a file" << endl;
return -1;
}
file = argv[1];
ifstream istr(file);
if (!istr.is_open()) {
return -1;
}
stringstream vcardStream;
vcardStream << istr.rdbuf();
string vcard = vcardStream.str();
BelCardParser *parser = new BelCardParser();
vcard = parser->unfold(vcard);
cout << vcard << endl;
delete parser;
return 0;
}
\ No newline at end of file
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
vcard-entity = 1*vcard
vcard = "BEGIN:VCARD" CRLF
"VERSION:4.0" CRLF
1*property
"END:VCARD" CRLF
"VERSION:4.0" CRLF
1*property
"END:VCARD" CRLF
property = (FN / N / NICKNAME) CRLF
property = (FN / N / NICKNAME / BDAY / ANNIVERSARY / GENDER) CRLF
FN = [group "."] "FN" *(";" any-param) ":" FN-value
FN-value = text
......@@ -21,12 +21,22 @@ N-suffixes = component *("," component)
NICKNAME = [group "."] "NICKNAME" *(";" any-param) ":" NICKNAME-value
NICKNAME-value = text-list
BDAY = [group "."] "BDAY" *(";" any-param) ":" BDAY-value
BDAY-value = date-and-or-time / text
ANNIVERSARY = [group "."] "ANNIVERSARY" *(";" any-param) ":" ANNIVERSARY-value
ANNIVERSARY-value = date-and-or-time / text
GENDER = [group "."] "GENDER" *(";" any-param) ":" GENDER-value
GENDER-value = [sex] [";" text]
sex = "M" / "F" / "O" / "N" / "U"
group = 1*(ALPHA / DIGIT / "-")
any-param = param-name "=" param-value
param-name = (iana-token / x-name)
param-value = param-value-component *("," param-value-component)
param-value-component = *SAFE-CHAR / DQUOTE *QSAFE-CHAR DQUOTE
param-value-component = *SAFE-CHAR / (DQUOTE *QSAFE-CHAR DQUOTE)
iana-token = 1*(ALPHA / DIGIT / "-")
x-name = "x-" 1*(ALPHA / DIGIT / "-")
......@@ -40,10 +50,55 @@ text = *TEXT-CHAR
TEXT-CHAR = "\\" / "\," / "\n" / WSP / NON-ASCII / %x21-2B / %x2D-5B / %x5D-7E
NON-ASCII = UTF8-2 / UTF8-3 / UTF8-4
QSAFE-CHAR = WSP / "!" / %x23-7E / NON-ASCII
SAFE-CHAR = WSP / "!" / %x23-39 / %x3C-7E / NON-ASCII
SAFE-CHAR = WSP / "!" / %x23-2B / %x2D-39 / %x3C-7E / NON-ASCII
VALUE-CHAR = WSP / VCHAR / NON-ASCII
UTF8-1 = %x00-7F
UTF8-2 = %xC2-DF UTF8-tail
UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) / %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) / %xF4 %x80-8F 2( UTF8-tail )
UTF8-tail = %x80-BF
date-list = date *("," date)
time-list = time *("," time)
date-time-list = date-time *("," date-time)
date-and-or-time-list = date-and-or-time *("," date-and-or-time)
timestamp-list = timestamp *("," timestamp)
integer-list = integer *("," integer)
float-list = float *("," float)
boolean = "TRUE" / "FALSE"
integer = [sign] 1*DIGIT
float = [sign] 1*DIGIT ["." 1*DIGIT]
sign = "+" / "-"
year = 4DIGIT ; 0000-9999
month = 2DIGIT ; 01-12
day = 2DIGIT ; 01-28/29/30/31 depending on month and leap year
hour = 2DIGIT ; 00-23
minute = 2DIGIT ; 00-59
second = 2DIGIT ; 00-58/59/60 depending on leap second
zone = utc-designator / utc-offset
utc-designator = %x5A ; uppercase "Z"
date = year [month day]
/ year "-" month
/ "--" month [day]
/ "--" "-" day
date-noreduc = year month day
/ "--" month day
/ "--" "-" day
date-complete = year month day
time = hour [minute [second]] [zone]
/ "-" minute [second]
/ "-" "-" second
time-notrunc = hour [minute [second]] [zone]
time-complete = hour minute second [zone]
time-designator = %x54 ; uppercase "T"
date-time = date-noreduc time-designator time-notrunc
timestamp = date-complete time-designator time-complete
date-and-or-time = date-time / date / time-designator time
utc-offset = sign hour [minute]
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