Commit b35d61cc authored by Sylvain Berfini's avatar Sylvain Berfini 🎩

Using a dedicated belr parser for identity addresses

parent 68abcf33
......@@ -82,6 +82,7 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
address/address-p.h
address/address.h
address/identity-address.h
address/identity-address-parser.h
c-wrapper/c-wrapper.h
c-wrapper/internal/c-sal.h
c-wrapper/internal/c-tools.h
......@@ -241,6 +242,7 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
address/address.cpp
address/identity-address.cpp
address/identity-address-parser.cpp
c-wrapper/api/c-address.cpp
c-wrapper/api/c-call-cbs.cpp
c-wrapper/api/c-call-params.cpp
......
/*
* identity-address-parser.cpp
* Copyright (C) 2019 Belledonne Communications SARL
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <set>
#include <unordered_map>
#include <belr/abnf.h>
#include <belr/grammarbuilder.h>
#include "linphone/utils/utils.h"
#include "logger/logger.h"
#include "object/object-p.h"
#include "identity-address-parser.h"
// =============================================================================
using namespace std;
LINPHONE_BEGIN_NAMESPACE
// -----------------------------------------------------------------------------
class IdentityAddressParserPrivate : public ObjectPrivate {
public:
shared_ptr<belr::Parser<shared_ptr<IdentityAddress> >> parser;
unordered_map<string, shared_ptr<IdentityAddress >> cache;
};
IdentityAddressParser::IdentityAddressParser () : Singleton(*new IdentityAddressParserPrivate) {
L_D();
const char *identityAddressGrammar =
"address = scheme \":\" [user] \"@\" host [ gruu-parameter ] \r\n"
"scheme = \"sip\" / \"sips\" \r\n"
"user = 1*( alphanum / escaped / \"-\" / \"+\" / \"_\" / \"~\" ) \r\n"
"escaped = \"%\" HEXDIG HEXDIG \r\n"
"host = 1*( alphanum / \".\" ) \r\n"
"gruu-parameter = \";gr=\" gruu-value \r\n"
"gruu-value = 1*( alphanum / \"-\" / \"_\" / \":\" ) \r\n"
"alphanum = ALPHA / DIGIT \r\n";
belr::ABNFGrammarBuilder builder;
shared_ptr<belr::Grammar> defaultGrammar = make_shared<belr::Grammar>("");
defaultGrammar->include(make_shared<belr::CoreRules>());
shared_ptr<belr::Grammar> grammar = builder.createFromAbnf(identityAddressGrammar, defaultGrammar);
//shared_ptr<belr::Grammar> grammar = belr::GrammarLoader::get().load(IdentityAddressGrammar);
if (!grammar)
lFatal() << "Unable to load Identity Address grammar.";
d->parser = make_shared<belr::Parser<shared_ptr<IdentityAddress>>>(grammar);
d->parser->setHandler("address", belr::make_fn(make_shared<IdentityAddress>))
->setCollector("scheme", belr::make_sfn(&IdentityAddress::setScheme))
->setCollector("user", belr::make_sfn(&IdentityAddress::setUsername))
->setCollector("host", belr::make_sfn(&IdentityAddress::setDomain))
->setCollector("gruu-value", belr::make_sfn(&IdentityAddress::setGruu));
}
// -----------------------------------------------------------------------------
shared_ptr<IdentityAddress> IdentityAddressParser::parseAddress (const string &input) {
L_D();
auto it = d->cache.find(input);
if (it == d->cache.end()) {
size_t parsedSize;
shared_ptr<IdentityAddress> identityAddress = d->parser->parseInput("Address", input, &parsedSize);
if (!identityAddress) {
lWarning() << "Unable to parse identity address from " << input;
return nullptr;
}
d->cache[input] = identityAddress;
return identityAddress;
} else {
return it->second;
}
}
LINPHONE_END_NAMESPACE
\ No newline at end of file
/*
* identity-address-parser.h
* Copyright (C) 2019 Belledonne Communications SARL
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _L_IDENTITY_ADDRESS_PARSER_H_
#define _L_IDENTITY_ADDRESS_PARSER_H_
#include "identity-address.h"
#include "object/singleton.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class IdentityAddressParserPrivate;
class IdentityAddressParser : public Singleton<IdentityAddressParser> {
friend class Singleton<IdentityAddressParser>;
public:
std::shared_ptr<IdentityAddress> parseAddress (const std::string &input);
private:
IdentityAddressParser ();
L_DECLARE_PRIVATE(IdentityAddressParser);
L_DISABLE_COPY(IdentityAddressParser);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _L_IDENTITY_ADDRESS_PARSER_H_
......@@ -20,6 +20,8 @@
#include "linphone/utils/utils.h"
#include "address.h"
#include "identity-address-parser.h"
#include "c-wrapper/c-wrapper.h"
#include "identity-address.h"
#include "logger/logger.h"
......@@ -45,12 +47,20 @@ public:
IdentityAddress::IdentityAddress (const string &address) : ClonableObject(*new IdentityAddressPrivate) {
L_D();
Address tmpAddress(address);
if (tmpAddress.isValid() && ((tmpAddress.getScheme() == "sip") || (tmpAddress.getScheme() == "sips"))) {
d->scheme = tmpAddress.getScheme();
d->username = tmpAddress.getUsername();
d->domain = tmpAddress.getDomain();
d->gruu = tmpAddress.getUriParamValue("gr");
shared_ptr<IdentityAddress> parsedAddress = IdentityAddressParser::getInstance()->parseAddress(address);
if (parsedAddress != nullptr) {
d->scheme = parsedAddress->getScheme();
d->username = parsedAddress->getUsername();
d->domain = parsedAddress->getDomain();
d->gruu = parsedAddress->getGruu();
} else {
Address tmpAddress(address);
if (tmpAddress.isValid() && ((tmpAddress.getScheme() == "sip") || (tmpAddress.getScheme() == "sips"))) {
d->scheme = tmpAddress.getScheme();
d->username = tmpAddress.getUsername();
d->domain = tmpAddress.getDomain();
d->gruu = tmpAddress.getUriParamValue("gr");
}
}
}
......@@ -71,6 +81,10 @@ IdentityAddress::IdentityAddress (const IdentityAddress &other) : ClonableObject
d->gruu = other.getGruu();
}
IdentityAddress::IdentityAddress () : ClonableObject(*new IdentityAddressPrivate) {
}
IdentityAddress &IdentityAddress::operator= (const IdentityAddress &other) {
L_D();
if (this != &other) {
......@@ -115,15 +129,19 @@ const string &IdentityAddress::getScheme () const {
return d->scheme;
}
void IdentityAddress::setScheme (const string &scheme) {
L_D();
d->scheme = scheme;
}
const string &IdentityAddress::getUsername () const {
L_D();
return d->username;
}
bool IdentityAddress::setUsername (const string &username) {
void IdentityAddress::setUsername (const string &username) {
L_D();
d->username = username;
return true;
}
const string &IdentityAddress::getDomain () const {
......@@ -131,10 +149,9 @@ const string &IdentityAddress::getDomain () const {
return d->domain;
}
bool IdentityAddress::setDomain (const string &domain) {
void IdentityAddress::setDomain (const string &domain) {
L_D();
d->domain = domain;
return true;
}
bool IdentityAddress::hasGruu () const {
......@@ -147,10 +164,9 @@ const string &IdentityAddress::getGruu () const {
return d->gruu;
}
bool IdentityAddress::setGruu (const string &gruu) {
void IdentityAddress::setGruu (const string &gruu) {
L_D();
d->gruu = gruu;
return true;
}
IdentityAddress IdentityAddress::getAddressWithoutGruu () const {
......
......@@ -33,9 +33,10 @@ class IdentityAddressPrivate;
class LINPHONE_PUBLIC IdentityAddress : public ClonableObject {
public:
explicit IdentityAddress (const std::string &address = "");
explicit IdentityAddress (const std::string &address);
IdentityAddress (const Address &address);
IdentityAddress (const IdentityAddress &other);
IdentityAddress ();
~IdentityAddress () = default;
IdentityAddress *clone () const override {
......@@ -52,16 +53,17 @@ public:
bool isValid () const;
const std::string &getScheme () const;
void setScheme (const std::string &scheme);
const std::string &getUsername () const;
bool setUsername (const std::string &username);
void setUsername (const std::string &username);
const std::string &getDomain () const;
bool setDomain (const std::string &domain);
void setDomain (const std::string &domain);
bool hasGruu () const;
const std::string &getGruu () const;
bool setGruu (const std::string &gruu);
void setGruu (const std::string &gruu);
IdentityAddress getAddressWithoutGruu () const;
......
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