Source

Target

Commits (2)
Showing with 201 additions and 25 deletions
......@@ -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;
......
......@@ -72,7 +72,7 @@ set(CERTIFICATE_CLIENT_FILES
certificates/client/cert2.pem
certificates/client/key2.pem
certificates/client/cert3.pem
certificates/client/key3.pem
certificates/client/key3.pem
certificates/client/cert2-signed-by-other-ca.pem
)
......@@ -82,6 +82,7 @@ set(DB_FILES
db/friends.db
db/linphone.db
db/messages.db
db/chatrooms.db
)
set(RC_FILES
......
File added
......@@ -37,9 +37,11 @@ using namespace LinphonePrivate;
class MainDbProvider {
public:
MainDbProvider () {
MainDbProvider () : MainDbProvider("db/linphone.db") { }
MainDbProvider (const char *db_file) {
mCoreManager = linphone_core_manager_create("marie_rc");
char *roDbPath = bc_tester_res("db/linphone.db");
char *roDbPath = bc_tester_res(db_file);
char *rwDbPath = bc_tester_file("linphone.db");
BC_ASSERT_FALSE(liblinphone_tester_copy_file(roDbPath, rwDbPath));
linphone_config_set_string(linphone_core_get_config(mCoreManager->lc), "storage", "uri", rwDbPath);
......@@ -62,7 +64,7 @@ private:
// -----------------------------------------------------------------------------
static void get_events_count () {
static void get_events_count (void) {
MainDbProvider provider;
const MainDb &mainDb = provider.getMainDb();
BC_ASSERT_EQUAL(mainDb.getEventCount(), 5175, int, "%d");
......@@ -72,7 +74,7 @@ static void get_events_count () {
BC_ASSERT_EQUAL(mainDb.getEventCount(MainDb::NoFilter), 5175, int, "%d");
}
static void get_messages_count () {
static void get_messages_count (void) {
MainDbProvider provider;
const MainDb &mainDb = provider.getMainDb();
BC_ASSERT_EQUAL(mainDb.getChatMessageCount(), 5157, int, "%d");
......@@ -84,7 +86,7 @@ static void get_messages_count () {
);
}
static void get_unread_messages_count () {
static void get_unread_messages_count (void) {
MainDbProvider provider;
const MainDb &mainDb = provider.getMainDb();
BC_ASSERT_EQUAL(mainDb.getUnreadChatMessageCount(), 2, int, "%d");
......@@ -96,7 +98,7 @@ static void get_unread_messages_count () {
);
}
static void get_history () {
static void get_history (void) {
MainDbProvider provider;
const MainDb &mainDb = provider.getMainDb();
BC_ASSERT_EQUAL(
......@@ -137,7 +139,7 @@ static void get_history () {
);
}
static void get_conference_notified_events () {
static void get_conference_notified_events (void) {
MainDbProvider provider;
const MainDb &mainDb = provider.getMainDb();
list<shared_ptr<EventLog>> events = mainDb.getConferenceNotifiedEvents(
......@@ -185,12 +187,21 @@ static void get_conference_notified_events () {
}
}
static void load_a_lot_of_chatrooms(void) {
chrono::high_resolution_clock::time_point start = chrono::high_resolution_clock::now();
MainDbProvider provider("db/chatrooms.db");
chrono::high_resolution_clock::time_point end = chrono::high_resolution_clock::now();
long ms = (long) chrono::duration_cast<chrono::milliseconds>(end - start).count();
BC_ASSERT_LOWER(ms, 1000, long, "%li");
}
test_t main_db_tests[] = {
TEST_NO_TAG("Get events count", get_events_count),
TEST_NO_TAG("Get messages count", get_messages_count),
TEST_NO_TAG("Get unread messages count", get_unread_messages_count),
TEST_NO_TAG("Get history", get_history),
TEST_NO_TAG("Get conference events", get_conference_notified_events)
TEST_NO_TAG("Get conference events", get_conference_notified_events),
TEST_NO_TAG("Load a lot of chatrooms", load_a_lot_of_chatrooms)
};
test_suite_t main_db_test_suite = {
......