PBAP: remove obsolete .orig source file

This was accidentally checked in when refactoring.
This commit is contained in:
Patrick Ohly 2014-04-02 14:35:38 +02:00
parent 841b737740
commit b80302cf67

View file

@ -1,345 +0,0 @@
/*
* Copyright (C) 2007-2009 Patrick Ohly <patrick.ohly@gmx.de>
* Copyright (C) 2009 Intel Corporation
* Copyright (C) 2012 BMW Car IT GmbH. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include "config.h"
#ifdef ENABLE_PBAP
#include "PbapSyncSource.h"
// SyncEvolution includes a copy of Boost header files.
// They are safe to use without creating additional
// build dependencies. boost::filesystem requires a
// library and therefore is avoided here. Some
// utility functions from SyncEvolution are used
// instead, plus standard C/Posix functions.
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/tokenizer.hpp>
#include <errno.h>
#include <unistd.h>
#include <pcrecpp.h>
#include <algorithm>
#include <syncevo/util.h>
#include "gdbus-cxx-bridge.h"
#include <boost/algorithm/string/predicate.hpp>
#include <boost/bind.hpp>
#include <syncevo/SyncContext.h>
#include <syncevo/declarations.h>
SE_BEGIN_CXX
#define OBC_SERVICE "org.openobex.client"
#define OBC_CLIENT_INTERFACE "org.openobex.Client"
#define OBC_PBAP_INTERFACE "org.openobex.PhonebookAccess"
class PbapSession {
public:
PbapSession(void);
void initSession(const std::string &address, const std::string &format);
typedef std::map<std::string, std::string> Content;
void pullAll(Content &dst);
void shutdown(void);
private:
GDBusCXX::DBusRemoteObject m_client;
std::auto_ptr<GDBusCXX::DBusRemoteObject> m_session;
};
PbapSession::PbapSession(void) :
m_client(GDBusCXX::dbus_get_bus_connection("SESSION", NULL, true, NULL),
"/", OBC_CLIENT_INTERFACE, OBC_SERVICE, true)
{
}
void PbapSession::initSession(const std::string &address, const std::string &format)
{
if (m_session.get()) {
return;
}
// format string uses:
// [(2.1|3.0):][^]propname,propname,...
//
// 3.0:^PHOTO = download in vCard 3.0 format, excluding PHOTO
// 2.1:PHOTO = download in vCard 2.1 format, only the PHOTO
std::string version;
std::string tmp;
std::string properties;
const pcrecpp::RE re("(?:(2\\.1|3\\.0):?)?(\\^?)([-a-zA-Z,]*)");
if (!re.FullMatch(format, &version, &tmp, &properties)) {
SE_THROW(StringPrintf("invalid specification of PBAP vCard format (databaseFormat): %s",
format.c_str()));
}
char negated = tmp.c_str()[0];
if (version.empty()) {
// same default as in obexd
version = "2.1";
}
if (version != "2.1" && version != "3.0") {
SE_THROW(StringPrintf("invalid vCard version prefix in PBAP vCard format specification (databaseFormat): %s",
format.c_str()));
}
std::set<std::string> keywords;
boost::split(keywords, properties, boost::is_from_range(',', ','));
typedef std::map<std::string, boost::variant<std::string> > Params;
GDBusCXX::DBusClientCall1<GDBusCXX::DBusObject_t>
createSession(m_client, "CreateSession");
Params params;
params["Destination"] = std::string(address);
params["Target"] = std::string("PBAP");
std::string session = createSession(params);
if (session.empty()) {
SE_THROW("PBAP: got empty session from CreateSession()");
}
m_session.reset(new GDBusCXX::DBusRemoteObject(m_client.getConnection(),
session,
OBC_PBAP_INTERFACE,
OBC_SERVICE,
true));
SE_LOG_DEBUG(NULL, NULL, "PBAP session created: %s", m_session->getPath());
// get filter list so that we can continue validating our format specifier
std::vector<std::string> filterFields =
GDBusCXX::DBusClientCall1< std::vector<std::string> >(*m_session, "ListFilterFields")();
std::list<std::string> filter;
if (negated) {
// negated, start with everything set
filter.insert(filter.begin(), filterFields.begin(), filterFields.end());
}
// validate parameters and update filter
BOOST_FOREACH (const std::string &prop, keywords) {
if (prop.empty()) {
continue;
}
std::vector<std::string>::const_iterator entry =
std::find_if(filterFields.begin(),
filterFields.end(),
boost::bind(&boost::iequals<std::string,std::string>, _1, prop, std::locale()));
if (entry == filterFields.end()) {
SE_THROW(StringPrintf("invalid property name in PBAP vCard format specification (databaseFormat): %s",
prop.c_str()));
}
if (negated) {
filter.remove(*entry);
} else {
filter.push_back(*entry);
}
}
GDBusCXX::DBusClientCall0(*m_session, "Select")(std::string("int"), std::string("PB"));
GDBusCXX::DBusClientCall0(*m_session, "SetFilter")(std::vector<std::string>(filter.begin(), filter.end()));
GDBusCXX::DBusClientCall0(*m_session, "SetFormat")(std::string(version == "2.1" ? "vcard21" : "vcard30"));
SE_LOG_DEBUG(NULL, NULL, "PBAP session initialized");
}
void vcardParse(const std::string &content, std::size_t begin, std::size_t end, std::map<std::string, std::string> &dst)
{
static const boost::char_separator<char> lineSep("\n\r");
typedef boost::tokenizer<boost::char_separator<char> > Tokenizer;
Tokenizer tok(content.begin() + begin, content.begin() + end, lineSep);
for(Tokenizer::iterator it = tok.begin(); it != tok.end(); it ++) {
const std::string &line = *it;
size_t i = line.find(':');
if(i != std::string::npos) {
std::size_t j = line.find(';');
j = (j == std::string::npos)? i : std::min(i, j);
std::string key = line.substr(0, j);
std::string value = line.substr(i + 1);
dst[key] = value;
}
}
}
void PbapSession::pullAll(Content &dst)
{
GDBusCXX::DBusClientCall1<std::string> pullall(*m_session, "PullAll");
std::string content = pullall();
// empty content not treated as an error
typedef std::map<std::string, int> CounterMap;
CounterMap counterMap;
std::size_t pos = 0;
int count = 0;
while(pos < content.size()) {
static const std::string beginStr("BEGIN:VCARD");
static const std::string endStr("END:VCARD");
pos = content.find(beginStr, pos);
if(pos == std::string::npos) {
break;
}
std::size_t endPos = content.find(endStr, pos + beginStr.size());
if(endPos == std::string::npos) {
break;
}
endPos += endStr.size();
typedef std::map<std::string, std::string> VcardMap;
VcardMap vcard;
vcardParse(content, pos, endPos, vcard);
VcardMap::const_iterator it = vcard.find("N");
if(it != vcard.end() && !it->second.empty()) {
const std::string &fn = it->second;
const std::pair<CounterMap::iterator, bool> &r =
counterMap.insert(CounterMap::value_type(fn, 0));
if(!r.second) {
r.first->second ++;
}
char suffix[8];
sprintf(suffix, "%07d", r.first->second);
std::string id = StringPrintf("%d", count); // fn + std::string(suffix);
dst[id] = content.substr(pos, endPos - pos);
}
pos = endPos;
count++;
}
SE_LOG_DEBUG(NULL, NULL, "PBAP content pulled: %d entries", (int) dst.size());
}
void PbapSession::shutdown(void)
{
GDBusCXX::DBusClientCall0 removeSession(m_client, "RemoveSession");
// always clear pointer, even if method call fails
GDBusCXX::DBusObject_t path(m_session->getPath());
m_session.reset();
SE_LOG_DEBUG(NULL, NULL, "removed session: %s", path.c_str());
removeSession(path);
SE_LOG_DEBUG(NULL, NULL, "PBAP session closed");
}
PbapSyncSource::PbapSyncSource(const SyncSourceParams &params) :
TrackingSyncSource(params)
{
m_session.reset(new PbapSession());
}
std::string PbapSyncSource::getMimeType() const
{
return "text/x-vcard";
}
std::string PbapSyncSource::getMimeVersion() const
{
return "2.1";
}
void PbapSyncSource::open()
{
string database = getDatabaseID();
const string prefix("obex-bt://");
if (!boost::starts_with(database, prefix)) {
throwError("database should specifiy device address (obex-bt://<bt-addr>)");
}
std::string address = database.substr(prefix.size());
m_session->initSession(address, getDatabaseFormat());
m_session->pullAll(m_content);
m_session->shutdown();
}
bool PbapSyncSource::isEmpty()
{
return m_content.empty();
}
void PbapSyncSource::close()
{
}
PbapSyncSource::Databases PbapSyncSource::getDatabases()
{
Databases result;
result.push_back(Database("select database via bluetooth address",
"[obex-bt://]<bt-addr>"));
return result;
}
void PbapSyncSource::listAllItems(RevisionMap_t &revisions)
{
typedef std::pair<std::string, std::string> Entry;
BOOST_FOREACH(const Entry &entry, m_content) {
revisions[entry.first] = "0";
}
}
void PbapSyncSource::readItem(const string &uid, std::string &item, bool raw)
{
Content::iterator it = m_content.find(uid);
if(it != m_content.end()) {
item = it->second;
}
}
TrackingSyncSource::InsertItemResult PbapSyncSource::insertItem(const string &uid, const std::string &item, bool raw)
{
throw std::runtime_error("Operation not supported");
}
void PbapSyncSource::removeItem(const string &uid)
{
throw std::runtime_error("Operation not supported");
}
SE_END_CXX
#endif /* ENABLE_PBAP */
#ifdef ENABLE_MODULES
# include "PbapSyncSourceRegister.cpp"
#endif