From: Mikel Astiz <[email protected]>

Populates the local cache with the addressbook given by the remote
device as result of PullAll().

The LUID is built from the full-name of the vcard entry, combined with a
suffix that avoid collisions in case of multiple entries with the same
full-name.
---
 src/backends/pbap/PbapSyncSource.cpp |   80 ++++++++++++++++++++++++++++++++++
 1 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/src/backends/pbap/PbapSyncSource.cpp 
b/src/backends/pbap/PbapSyncSource.cpp
index 0277e7e..302aadc 100644
--- a/src/backends/pbap/PbapSyncSource.cpp
+++ b/src/backends/pbap/PbapSyncSource.cpp
@@ -69,6 +69,7 @@ private:
     void createSessionCb(const GDBusCXX::DBusObject_t &session,
                          const string &error);
     void selectCb(const string &error);
+    void pullAllCb(Content *dst, const std::string &content, const string 
&error);
     void removeSessionCb(const string &error);
 
     static GMainLoop *s_mainloop;
@@ -160,6 +161,85 @@ void PbapSession::selectCb(const string &error)
 
 void PbapSession::pullAll(Content &dst)
 {
+    GDBusCXX::DBusClientCall1<std::string> method(*m_session, "PullAll");
+    method(boost::bind(&PbapSession::pullAllCb, this, &dst, _1, _2));
+
+    runMainLoop();
+}
+
+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 : j;
+            std::string key = line.substr(0, j);
+            std::string value = line.substr(i + 1);
+            dst[key] = value;
+        }
+    }
+}
+
+void PbapSession::pullAllCb(Content *dst, const std::string &content, const 
string &error)
+{
+    if(!error.empty() || content.empty()) {
+        SE_LOG_ERROR(NULL, NULL, "Error in calling method PullAll of interface 
org.openobex.PhonebookAccess: %s", error.c_str());
+        exitMainLoop(new std::runtime_error(error));
+        return;
+    }
+
+    typedef std::map<std::string, int> CounterMap;
+    CounterMap counterMap;
+
+    std::size_t pos = 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("FN");
+        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 = fn + std::string(suffix);
+            (*dst)[id] = content.substr(pos, endPos);
+        }
+
+        pos = endPos;
+    }
+
+    exitMainLoop();
 }
 
 void PbapSession::shutdown(void)
-- 
1.7.6.5

_______________________________________________
SyncEvolution mailing list
[email protected]
http://lists.syncevolution.org/listinfo/syncevolution

Reply via email to