summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Ohly <patrick.ohly@gmx.de>2007-10-04 20:54:27 +0000
committerPatrick Ohly <patrick.ohly@gmx.de>2007-10-04 20:54:27 +0000
commit4aa53726875c218f600b8f8df5575809c3d92c9c (patch)
tree40bb6f812c3ee38e353f31fdbcd316f323032c3b
parent691090fbccec52663453492acb03c8de46781717 (diff)
port to iPhone: lots of hacks and debug output, none of the multiprops supported yet (use unknown format in API)
git-svn-id: https://zeitsenke.de/svn/SyncEvolution/trunk@399 15ad00c4-1369-45f4-8270-35d70d36bdcd
-rw-r--r--HACKING16
-rw-r--r--configure.in15
-rw-r--r--src/AddressBookConstants.cpp47
-rw-r--r--src/AddressBookSource.cpp329
-rw-r--r--src/AddressBookSource.h3
5 files changed, 329 insertions, 81 deletions
diff --git a/HACKING b/HACKING
index d89f3a63..3f8104b3 100644
--- a/HACKING
+++ b/HACKING
@@ -153,3 +153,19 @@ that address book syncing uses the default libraries):
apt-cache showpkg libecal-dev libedata-cal-dev
ver=1.4.1-0zoh4; for i in libecal-dev libecal libedata-cal libedata-cal-dev; do wget http://maemo.o-hand.com/packages/mistral/${i}_${ver}_armel.deb; done
dpkg --force-depends -i *.deb
+
+- compiling for iPhone:
+ Requires iPhone toolchain and libcurl, ideally configured as small as possible
+ and statically (to avoid packaging problems):
+ ./configure --prefix=/usr/local/iphone --host=arm-apple-darwin --disable-shared \
+ --disable-crypto-auth --without-gnutls --without-ssl --without-zlib \
+ --without-libssh2 --disable-ipv6 --disable-manual --disable-telnet \
+ --disable-tftp --disable-ldap --disable-file --disable-ftp
+ manually set HAVE_POSIX_STRERROR_R in lib/config.h
+
+ Potential problems with toolchain:
+ std++ not found: ln -s libstdc++.6.dylib /usr/local/iphone-filesystem/usr/lib/libstdc++.dylib
+ AddressBook framework must be added to iphone-dev/include/install-headers.sh.in
+
+ Compile with curl-config in the PATH:
+ PATH=/usr/local/iphone/bin/:$PATH ~/projects/sync4jevolution/configure --host=arm-apple-darwin --with-sync4j-src=/home/patrick/projects/native CXXFLAGS=-g --disable-ecal --disable-ebook --enable-addressbook \ No newline at end of file
diff --git a/configure.in b/configure.in
index 4f166688..ea9b88c1 100644
--- a/configure.in
+++ b/configure.in
@@ -222,6 +222,7 @@ AC_SUBST(SQLITE_LIBS)
dnl hard-coded settings for Mac OS X AddressBook
ADDRESSBOOK_CFLAGS=
+
ADDRESSBOOK_LIBS="-framework AddressBook -framework CoreFoundation"
AC_SUBST(ADDRESSBOOK_CFLAGS)
AC_SUBST(ADDRESSBOOK_LIBS)
@@ -285,9 +286,6 @@ PKG_CHECK_MODULES(GLIB, "glib-2.0", GLIBFOUND=yes, GLIBFOUND=no)
if test "x${GLIBFOUND}" = "xno"; then
PKG_CHECK_MODULES(GLIB, "glib", GLIBFOUND=yes, GLIBFOUND=no)
fi
-if test "x${GLIBFOUND}" = "xyes"; then
- AC_DEFINE(HAVE_GLIB, 1, [glib found])
-fi
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
@@ -310,6 +308,17 @@ if test "$enable_addressbook" == "yes"; then
SYNCEVOLUTION_MODULES="$SYNCEVOLUTION_MODULES syncaddressbook.la"
fi
+dnl glib initialization is done only for libebook and libecal, not needed
+dnl otherwise even if found
+if test "$enable_ebook" != "yes" && test "$enable_ecal" != "yes"; then
+ GLIB_CFLAGS=
+ GLIB_LIBS=
+else
+ if test "x${GLIBFOUND}" = "xyes"; then
+ AC_DEFINE(HAVE_GLIB, 1, [glib found])
+ fi
+fi
+
dnl figure out whether we link all code statically or as modules
if test "$enable_shared" == "yes"; then
SYNCEVOLUTION_LTLIBRARIES="$SYNCEVOLUTION_MODULES"
diff --git a/src/AddressBookConstants.cpp b/src/AddressBookConstants.cpp
index f84a3477..050c9fd8 100644
--- a/src/AddressBookConstants.cpp
+++ b/src/AddressBookConstants.cpp
@@ -19,10 +19,17 @@
#include <CoreFoundation/CoreFoundation.h>
-/** constants missing from AddressBook framework on iPhone */
+/**
+ * constants missing from AddressBook framework on iPhone: use strings
+ * as found in SQLite database on iPhone
+ *
+ * kABTitleProperty is also missing, but the ABRecord constants which
+ * are CFStrings on Mac OS seem to be numeric constants on the iPhone so
+ * we cannot guess it might be (if it exists at all), so not supported.
+ */
#ifdef __arm__
-CFStringRef kABCAIMInstantProperty;
+// CFStringRef kABCAIMInstantProperty;
CFStringRef kABCAddressCityKey;
CFStringRef kABCAddressCountryKey;
CFStringRef kABCAddressHomeLabel;
@@ -34,14 +41,14 @@ CFStringRef kABCAssistantLabel;
CFStringRef kABCEmailHomeLabel;
CFStringRef kABCEmailWorkLabel;
CFStringRef kABCHomePageLabel;
-CFStringRef kABCHomePageProperty;
-CFStringRef kABCICQInstantProperty;
+// CFStringRef kABCHomePageProperty;
+// CFStringRef kABCICQInstantProperty;
CFStringRef kABCJabberHomeLabel;
-CFStringRef kABCJabberInstantProperty;
+// CFStringRef kABCJabberInstantProperty;
CFStringRef kABCJabberWorkLabel;
-CFStringRef kABCMSNInstantProperty;
+// CFStringRef kABCMSNInstantProperty;
CFStringRef kABCManagerLabel;
-CFStringRef kABCOtherDatesProperty;
+// CFStringRef kABCOtherDatesProperty;
CFStringRef kABCPhoneHomeFAXLabel;
CFStringRef kABCPhoneHomeLabel;
CFStringRef kABCPhoneMainLabel;
@@ -50,16 +57,16 @@ CFStringRef kABCPhonePagerLabel;
CFStringRef kABCPhoneWorkFAXLabel;
CFStringRef kABCPhoneWorkLabel;
CFStringRef kABCSpouseLabel;
-CFStringRef kABCTitleProperty;
-CFStringRef kABCURLsProperty;
-CFStringRef kABCYahooInstantProperty;
+// CFStringRef kABCTitleProperty;
+// CFStringRef kABCURLsProperty;
+// CFStringRef kABCYahooInstantProperty;
#endif
class constants {
public:
constants() {
#ifdef __arm__
- kABCAIMInstantProperty = CFStringCreateWithCString(NULL, "AIMInstant", kCFStringEncodingUTF8);
+ // kABCAIMInstantProperty = CFStringCreateWithCString(NULL, "AIMInstant", kCFStringEncodingUTF8);
kABCAddressCityKey = CFStringCreateWithCString(NULL, "City", kCFStringEncodingUTF8);
kABCAddressCountryKey = CFStringCreateWithCString(NULL, "Country", kCFStringEncodingUTF8);
kABCAddressHomeLabel = CFStringCreateWithCString(NULL, "_$!<Home>!$_", kCFStringEncodingUTF8);
@@ -71,14 +78,14 @@ public:
kABCEmailHomeLabel = CFStringCreateWithCString(NULL, "_$!<Home>!$_", kCFStringEncodingUTF8);
kABCEmailWorkLabel = CFStringCreateWithCString(NULL, "_$!<Work>!$_", kCFStringEncodingUTF8);
kABCHomePageLabel = CFStringCreateWithCString(NULL, "_$!<HomePage>!$_", kCFStringEncodingUTF8);
- kABCHomePageProperty = CFStringCreateWithCString(NULL, "HomePage", kCFStringEncodingUTF8);
- kABCICQInstantProperty = CFStringCreateWithCString(NULL, "ICQInstant", kCFStringEncodingUTF8);
+ // kABCHomePageProperty = CFStringCreateWithCString(NULL, "HomePage", kCFStringEncodingUTF8);
+ // kABCICQInstantProperty = CFStringCreateWithCString(NULL, "ICQInstant", kCFStringEncodingUTF8);
kABCJabberHomeLabel = CFStringCreateWithCString(NULL, "_$!<Home>!$_", kCFStringEncodingUTF8);
- kABCJabberInstantProperty = CFStringCreateWithCString(NULL, "JabberInstant", kCFStringEncodingUTF8);
+ // kABCJabberInstantProperty = CFStringCreateWithCString(NULL, "JabberInstant", kCFStringEncodingUTF8);
kABCJabberWorkLabel = CFStringCreateWithCString(NULL, "_$!<Work>!$_", kCFStringEncodingUTF8);
- kABCMSNInstantProperty = CFStringCreateWithCString(NULL, "MSNInstant", kCFStringEncodingUTF8);
+ // kABCMSNInstantProperty = CFStringCreateWithCString(NULL, "MSNInstant", kCFStringEncodingUTF8);
kABCManagerLabel = CFStringCreateWithCString(NULL, "_$!<Manager>!$_", kCFStringEncodingUTF8);
- kABCOtherDatesProperty = CFStringCreateWithCString(NULL, "ABDate", kCFStringEncodingUTF8);
+ // kABCOtherDatesProperty = CFStringCreateWithCString(NULL, "ABDate", kCFStringEncodingUTF8);
kABCPhoneHomeFAXLabel = CFStringCreateWithCString(NULL, "_$!<HomeFAX>!$_", kCFStringEncodingUTF8);
kABCPhoneHomeLabel = CFStringCreateWithCString(NULL, "_$!<Home>!$_", kCFStringEncodingUTF8);
kABCPhoneMainLabel = CFStringCreateWithCString(NULL, "_$!<Main>!$_", kCFStringEncodingUTF8);
@@ -87,9 +94,9 @@ public:
kABCPhoneWorkFAXLabel = CFStringCreateWithCString(NULL, "_$!<WorkFAX>!$_", kCFStringEncodingUTF8);
kABCPhoneWorkLabel = CFStringCreateWithCString(NULL, "_$!<Work>!$_", kCFStringEncodingUTF8);
kABCSpouseLabel = CFStringCreateWithCString(NULL, "_$!<Spouse>!$_", kCFStringEncodingUTF8);
- kABCTitleProperty = CFStringCreateWithCString(NULL, "Title", kCFStringEncodingUTF8);
- kABCURLsProperty = CFStringCreateWithCString(NULL, "URLs", kCFStringEncodingUTF8);
- kABCYahooInstantProperty = CFStringCreateWithCString(NULL, "YahooInstant", kCFStringEncodingUTF8);
+ // kABCTitleProperty = CFStringCreateWithCString(NULL, "Title", kCFStringEncodingUTF8);
+ // kABCURLsProperty = CFStringCreateWithCString(NULL, "URLs", kCFStringEncodingUTF8);
+ // kABCYahooInstantProperty = CFStringCreateWithCString(NULL, "YahooInstant", kCFStringEncodingUTF8);
#endif
#if 0
@@ -122,7 +129,7 @@ public:
printconstant(kABPhoneWorkFAXLabel);
printconstant(kABPhoneWorkLabel);
printconstant(kABSpouseLabel);
- printconstant(kABTitleProperty);
+ // printconstant(kABTitleProperty);
printconstant(kABURLsProperty);
printconstant(kABYahooInstantProperty);
#endif
diff --git a/src/AddressBookSource.cpp b/src/AddressBookSource.cpp
index 61ccff01..c71f8096 100644
--- a/src/AddressBookSource.cpp
+++ b/src/AddressBookSource.cpp
@@ -26,6 +26,77 @@ using namespace std;
#ifdef ENABLE_ADDRESSBOOK
+#ifdef __arm__
+// On the iPhone the API is different, but the changes mostly seem to
+// consist of renames. Some constants and the vcard conversion
+// functions are missing. Unique IDs are integers, not string references.
+
+# define ABAddRecord ABCAddRecord
+# define ABCopyArrayOfAllPeople ABCCopyArrayOfAllPeople
+# define ABGetSharedAddressBook ABCGetSharedAddressBook
+# define ABMultiValueAdd ABCMultiValueAdd
+# define ABMultiValueCopyLabelAtIndex ABCMultiValueCopyLabelAtIndex
+# define ABMultiValueCopyValueAtIndex ABCMultiValueCopyValueAtIndex
+# define ABMultiValueCount ABCMultiValueGetCount
+# define ABMultiValueCreateMutable ABCMultiValueCreateMutable
+# define ABPersonCopyImageData ABCPersonCopyImageData
+# define PersonCreateWrapper(_addressbook) ABCPersonCreateNewPerson(_addressbook)
+# define ABPersonSetImageData ABCPersonSetImageData
+# define ABRecordCopyValue ABCRecordCopyValue
+# define ABRecordRemoveValue ABCRecordRemoveValue
+# define ABRecordSetValue ABCRecordSetValue
+# define ABRemoveRecord ABCRemoveRecord
+# define ABSave ABCSave
+# define kABAIMInstantProperty kABCAIMInstantProperty
+# define kABAddressCityKey kABCAddressCityKey
+# define kABAddressCountryKey kABCAddressCountryKey
+# define kABAddressHomeLabel kABCAddressHomeLabel
+# define kABAddressProperty kABCAddressProperty
+# define kABAddressStateKey kABCAddressStateKey
+# define kABAddressStreetKey kABCAddressStreetKey
+# define kABAddressWorkLabel kABCAddressWorkLabel
+# define kABAddressZIPKey kABCAddressZIPKey
+# define kABAssistantLabel kABCAssistantLabel
+# define kABBirthdayProperty kABCBirthdayProperty
+# define kABCreationDateProperty kABCCreationDateProperty
+# define kABDepartmentProperty kABCDepartmentProperty
+# define kABEmailHomeLabel kABCEmailHomeLabel
+# define kABEmailProperty kABCEmailProperty
+# define kABEmailWorkLabel kABCEmailWorkLabel
+# define kABFirstNameProperty kABCFirstNameProperty
+# define kABHomePageLabel kABCHomePageLabel
+/* # define kABHomePageProperty kABCHomePageProperty */
+# define kABICQInstantProperty kABCICQInstantProperty
+# define kABJabberHomeLabel kABCJabberHomeLabel
+# define kABJabberInstantProperty kABCJabberInstantProperty
+# define kABJabberWorkLabel kABCJabberWorkLabel
+# define kABJobTitleProperty kABCJobTitleProperty
+# define kABLastNameProperty kABCLastNameProperty
+# define kABMSNInstantProperty kABCMSNInstantProperty
+# define kABManagerLabel kABCManagerLabel
+# define kABMiddleNameProperty kABCMiddleNameProperty
+# define kABModificationDateProperty kABCModificationDateProperty
+# define kABNicknameProperty kABCNicknameProperty
+# define kABNoteProperty kABCNoteProperty
+# define kABOrganizationProperty kABCOrganizationProperty
+# define kABOtherDatesProperty kABCOtherDatesProperty
+# define kABPhoneHomeFAXLabel kABCPhoneHomeFAXLabel
+# define kABPhoneHomeLabel kABCPhoneHomeLabel
+# define kABPhoneMainLabel kABCPhoneMainLabel
+# define kABPhoneMobileLabel kABCPhoneMobileLabel
+# define kABPhonePagerLabel kABCPhonePagerLabel
+# define kABPhoneProperty kABCPhoneProperty
+# define kABPhoneWorkFAXLabel kABCPhoneWorkFAXLabel
+# define kABPhoneWorkLabel kABCPhoneWorkLabel
+# define kABRelatedNamesProperty kABCRelatedNamesProperty
+# define kABSpouseLabel kABCSpouseLabel
+# define kABSuffixProperty kABCSuffixProperty
+// # define kABTitleProperty kABCTitleProperty
+// # define kABURLsProperty kABCURLsProperty
+# define kABYahooInstantProperty kABCYahooInstantProperty
+#else
+# #define PersonCreateWrapper(_addressbook) ABPersonCreate()
+#endif
#include "AddressBookSource.h"
#include <common/base/Log.h>
@@ -62,6 +133,30 @@ static CFStringRef Std2CFString(const string &str)
return cfstring.release();
}
+#ifdef __arm__
+
+extern "C" const CFStringRef kABCHomePageProperty;
+extern "C" const CFStringRef kABCURLProperty;
+
+extern "C" ABPersonRef ABCPersonCreateNewPerson(ABAddressBookRef addressbook);
+
+extern "C" ABRecordRef ABCPersonGetRecordForUniqueID(ABAddressBookRef addressBook, SInt32 uid);
+extern "C" ABRecordRef ABCopyRecordForUniqueId(ABAddressBookRef addressBook, CFStringRef uniqueId)
+{
+ SInt32 uid = CFStringGetIntValue(uniqueId);
+ return ABCPersonGetRecordForUniqueID(addressBook, uid);
+}
+
+extern "C" SInt32 ABCRecordGetUniqueId(ABRecordRef record);
+extern "C" CFStringRef ABRecordCopyUniqueId(ABRecordRef record)
+{
+ SInt32 uid = ABCRecordGetUniqueId(record);
+ return CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), uid);
+}
+
+#endif
+
+
/**
* a strtok_r() which does no skip delimiters at the start and end and does
* not merge consecutive delimiters, i.e. returned string may be empty
@@ -108,21 +203,39 @@ public:
// Remove all properties from person that we might set:
// those still found in the vCard will be recreated.
// Properties that we do not support are left untouched.
+ LOG.debug("removing values");
for (int mapindex = 0;
m_mapping[mapindex].m_vCardProp;
mapindex++) {
+ printf(" mapindex %d\n", mapindex);
const mapping &map = m_mapping[mapindex];
if (map.m_abPersonProp) {
- if (!ABRecordRemoveValue(m_person, map.m_abPersonProp)) {
- throw runtime_error("removing old value " + CFString2Std(map.m_abPersonProp) + " failed");
+ if (!ABRecordRemoveValue(m_person, *map.m_abPersonProp)) {
+ throw runtime_error("removing old value "
+#ifndef __arm__
+ + CFString2Std(*map.m_abPersonProp) + " " +
+#endif
+ "failed");
}
}
}
+ for (int multi = 0; multi < MAX_MULTIVALUE; multi++) {
+ printf(" multi %d\n", multi);
+ if (!ABRecordRemoveValue(m_person, *m_multiProp[multi])) {
+ throw runtime_error("removing old value "
+#ifndef __arm__
+ + CFString2Std(**m_multiProp[multi]) + " " +
+#endif
+ "failed");
+ }
+ }
// walk through all properties and handle them
int propindex = 0;
VProperty *vprop;
+ LOG.debug("storing properties in contact");
while ((vprop = vobj->getProperty(propindex)) != NULL) {
+ LOG.debug("property %s", vprop->getName());
for (int mapindex = 0;
m_mapping[mapindex].m_vCardProp;
mapindex++) {
@@ -133,6 +246,7 @@ public:
handler = &vCard2ABPerson::toPersonString;
}
(this->*handler)(map, *vprop);
+ LOG.debug("property %s handled", vprop->getName());
break;
}
}
@@ -140,12 +254,14 @@ public:
}
// now copy all those values to the person which did not map directly
+ LOG.debug("set multiprops");
for (int multi = 0; multi < MAX_MULTIVALUE; multi++) {
if (m_multi[multi]) {
- setPersonProp(m_multiProp[multi], m_multi[multi]);
+ setPersonProp(*m_multiProp[multi], m_multi[multi]);
}
}
+ LOG.debug("set photo");
VProperty *photo = vobj->getProperty("PHOTO");
if (photo) {
int len;
@@ -155,6 +271,8 @@ public:
throw runtime_error("cannot set photo data");
}
}
+
+ LOG.debug("contact done");
}
void fromPerson() {
@@ -162,7 +280,7 @@ public:
const unsigned char *text;
// VObject is so broken that it neither as a reset nor
- // an assignment operator - no I didn't write it :-/
+ // an assignment operator - no, I didn't write it :-/
//
// Reseting m_vobj was supposed to allow repeated calls
// to fromPerson, but this is not really necessary.
@@ -177,14 +295,24 @@ public:
m_mapping[mapindex].m_vCardProp;
mapindex++ ) {
const mapping &map = m_mapping[mapindex];
+ printf("%d: ", mapindex);
+ printf("%s prop %p = %p\n",
+ map.m_vCardProp,
+ map.m_abPersonProp,
+ map.m_abPersonProp ? *map.m_abPersonProp : 0);
if (map.m_abPersonProp) {
- ref<CFTypeRef> value(ABRecordCopyValue(m_person, map.m_abPersonProp));
+ ref<CFTypeRef> value(ABRecordCopyValue(m_person, *map.m_abPersonProp));
+ printf("got %p\n", (CFTypeRef)value);
if (value) {
+ ref<CFStringRef> descr(CFCopyDescription(value));
+ printf(" = %s\n",
+ CFString2Std(descr).c_str());
fromPerson_t handler = map.m_fromPerson;
if (!handler) {
handler = &vCard2ABPerson::fromPersonString;
}
(this->*handler)(map, value);
+ printf(" handled\n");
}
}
}
@@ -225,10 +353,11 @@ public:
m_vobj.fromNativeEncoding();
arrayptr<char> finalstr(m_vobj.toString(), "VOCL string");
m_vcard = (char *)finalstr;
+ LOG.debug("extracted %s",
+ (char *)finalstr);
}
private:
- string m_errorPrefix;
string &m_vcard;
ABPersonRef m_person;
VObject m_vobj;
@@ -252,21 +381,27 @@ private:
/** intermediate storage for multi-value data later passed to ABPerson - keep in sync with m_multiProp */
enum {
- URLS,
EMAILS,
PHONES,
+#ifndef __arm__
DATES,
- NAMES,
- ADDRESSES,
AIM,
JABBER,
MSN,
YAHOO,
ICQ,
+#endif
+ NAMES,
+ ADDRESSES,
MAX_MULTIVALUE
};
ref<ABMutableMultiValueRef> m_multi[MAX_MULTIVALUE];
- static const CFStringRef m_multiProp[MAX_MULTIVALUE];
+ /**
+ * the ABPerson property which corresponds to the m_multi array:
+ * a pointer because the tool chain for the iPhone did not properly
+ * handle the constants
+ */
+ static const CFStringRef *m_multiProp[MAX_MULTIVALUE];
struct mapping;
typedef void (vCard2ABPerson::*toPerson_t)(const mapping &map, VProperty &vprop);
@@ -281,10 +416,12 @@ private:
setPersonProp(property, cfstring);
}
void setPersonProp(CFStringRef property, CFTypeRef cftype) {
+ ref<CFStringRef> descr(CFCopyDescription(cftype));
+ LOG.debug("setting property %p to %s", property, CFString2Std(descr).c_str());
if (!ABRecordSetValue(m_person, property, cftype)) {
- ref<CFStringRef> descr(CFCopyDescription(cftype));
throwError("setting " + CFString2Std(property) + " to '" + CFString2Std(descr) + "'");
}
+ LOG.debug("setting done");
}
/**
@@ -293,8 +430,8 @@ private:
static const struct mapping {
/** the name of the vCard property, e.g. "ADDR" */
const char *m_vCardProp;
- /** the predefined string reference for an ABPerson property */
- CFStringRef m_abPersonProp;
+ /** address of ABPerson property, NULL pointer if none matches directly */
+ const CFStringRef *m_abPersonProp;
/** called when the property is found in the VObject: default is to copy string */
toPerson_t m_toPerson;
/** called when the property is found in the ABPerson: default is to copy string */
@@ -315,7 +452,8 @@ private:
if (!value) {
value = "";
}
- setPersonProp(map.m_abPersonProp, value);
+ // assert(map.m_abPersonProp);
+ setPersonProp(*map.m_abPersonProp, value);
}
void fromPersonStoreString(const mapping &map, CFTypeRef cftype) {
@@ -342,12 +480,15 @@ private:
date.day = day;
ref<CFDateRef> cfdate(CFDateCreate(NULL, CFGregorianDateGetAbsoluteTime(date, NULL)));
if (cfdate) {
- setPersonProp(map.m_abPersonProp, cfdate);
+ // assert(map.m_abPersonProp);
+ setPersonProp(*map.m_abPersonProp, cfdate);
}
}
}
void fromPersonURLs(const mapping &map, CFTypeRef cftype) {
+#ifndef __arm__
+ // TODO: figure out what kABCURLProperty stands for
int index = ABMultiValueCount((ABMultiValueRef)cftype) - 1;
while (index >= 0) {
ref<CFStringRef> label((CFStringRef)ABMultiValueCopyLabelAtIndex((ABMultiValueRef)cftype, index), "label");
@@ -364,6 +505,7 @@ private:
index--;
}
+#endif
}
void fromPersonEMail(const mapping &map, CFTypeRef cftype) {
@@ -389,6 +531,8 @@ private:
}
}
void toPersonEMail(const mapping &map, VProperty &vprop) {
+#ifndef __arm__
+ // TODO: crashes on iPhone
const char *value = vprop.getValue();
arrayptr<char> buffer(wstrdup(value ? value : ""));
char *saveptr, *endptr;
@@ -416,6 +560,7 @@ private:
} else {
ref<CFStringRef> cfres(res);
}
+#endif
}
void fromPersonAddr(const mapping &map, CFTypeRef cftype) {
@@ -571,6 +716,8 @@ private:
}
}
void toPersonPhone(const mapping &map, VProperty &vprop) {
+#ifndef __arm__
+ // TODO: crashes on iPhone
const char *value = vprop.getValue();
arrayptr<char> buffer(wstrdup(value ? value : ""));
char *saveptr, *endptr;
@@ -612,6 +759,7 @@ private:
} else {
ref<CFStringRef> cfres(res);
}
+#endif
}
void fromPersonChat(const mapping &map, CFTypeRef cftype) {
@@ -688,7 +836,9 @@ private:
if (!prefix) {
return;
}
+#ifndef __arm__
setPersonProp(kABTitleProperty, prefix);
+#endif
char *suffix = my_strtok_r(NULL, VObject::SEMICOLON_REPLACEMENT, &saveptr, &endptr);
if (!suffix) {
@@ -747,58 +897,66 @@ private:
}
};
-const CFStringRef vCard2ABPerson::m_multiProp[MAX_MULTIVALUE] = {
- (CFStringRef)kABURLsProperty,
- kABEmailProperty,
- kABPhoneProperty,
- kABOtherDatesProperty,
- kABRelatedNamesProperty,
- kABAddressProperty,
- kABAIMInstantProperty,
- kABJabberInstantProperty,
- kABMSNInstantProperty,
- kABYahooInstantProperty,
- kABICQInstantProperty
+const CFStringRef *vCard2ABPerson::m_multiProp[MAX_MULTIVALUE] = {
+ &kABEmailProperty,
+ &kABPhoneProperty,
+#ifndef __arm__
+ &kABOtherDatesProperty,
+ &kABAIMInstantProperty,
+ &kABJabberInstantProperty,
+ &kABMSNInstantProperty,
+ &kABYahooInstantProperty,
+ &kABICQInstantProperty,
+#endif
+ &kABRelatedNamesProperty,
+ &kABAddressProperty
};
const vCard2ABPerson::mapping vCard2ABPerson::m_mapping[] = {
- { "", kABFirstNameProperty, NULL, &vCard2ABPerson::fromPersonStoreString, FIRST_NAME },
- { "", kABLastNameProperty, NULL, &vCard2ABPerson::fromPersonStoreString, LAST_NAME },
- { "", kABMiddleNameProperty, NULL, &vCard2ABPerson::fromPersonStoreString, MIDDLE_NAME },
- { "", kABTitleProperty, NULL, &vCard2ABPerson::fromPersonStoreString, TITLE },
- { "", kABSuffixProperty, NULL, &vCard2ABPerson::fromPersonStoreString, SUFFIX },
+ { "", &kABFirstNameProperty, NULL, &vCard2ABPerson::fromPersonStoreString, FIRST_NAME },
+ { "", &kABLastNameProperty, NULL, &vCard2ABPerson::fromPersonStoreString, LAST_NAME },
+ { "", &kABMiddleNameProperty, NULL, &vCard2ABPerson::fromPersonStoreString, MIDDLE_NAME },
+#ifndef __arm__
+ { "", &kABTitleProperty, NULL, &vCard2ABPerson::fromPersonStoreString, TITLE },
+#endif
+ { "", &kABSuffixProperty, NULL, &vCard2ABPerson::fromPersonStoreString, SUFFIX },
{ "N", 0, &vCard2ABPerson::toPersonName },
/* "FN" */
/* kABFirstNamePhoneticProperty */
/* kABLastNamePhoneticProperty */
/* kABMiddleNamePhoneticProperty */
- { "BDAY", kABBirthdayProperty, &vCard2ABPerson::toPersonDate, &vCard2ABPerson::fromPersonDate },
+ { "BDAY", &kABBirthdayProperty, &vCard2ABPerson::toPersonDate, &vCard2ABPerson::fromPersonDate },
- { "", kABOrganizationProperty, NULL, &vCard2ABPerson::fromPersonStoreString, ORGANIZATION },
- { "", kABDepartmentProperty, NULL, &vCard2ABPerson::fromPersonStoreString, DEPARTMENT },
+ { "", &kABOrganizationProperty, NULL, &vCard2ABPerson::fromPersonStoreString, ORGANIZATION },
+ { "", &kABDepartmentProperty, NULL, &vCard2ABPerson::fromPersonStoreString, DEPARTMENT },
{ "ORG", 0, &vCard2ABPerson::toPersonOrg },
- { "TITLE", kABJobTitleProperty },
+ { "TITLE", &kABJobTitleProperty },
/* "ROLE" */
+#ifdef __arm__
+ // TODO: { "", &kABCURLProperty, NULL, &vCard2ABPerson::fromPersonURLs },
+#else
/**
* bug in the header files for kABHomePageProperty and kABURLsProperty,
* typecast required
*/
- { "URL", (CFStringRef)kABHomePageProperty },
- { "", (CFStringRef)kABURLsProperty, NULL, &vCard2ABPerson::fromPersonURLs },
+ { "URL", (CFStringRef *)&kABHomePageProperty },
+ { "", (CFStringRef *)&kABURLsProperty, NULL, &vCard2ABPerson::fromPersonURLs },
+#endif
#if 0
kABHomePageLabel
#endif
- { "EMAIL", kABEmailProperty, &vCard2ABPerson::toPersonEMail, &vCard2ABPerson::fromPersonEMail, EMAILS },
+#ifndef __arm__
+ { "EMAIL", &kABEmailProperty, &vCard2ABPerson::toPersonEMail, &vCard2ABPerson::fromPersonEMail, EMAILS },
#if 0
kABEmailWorkLabel
kABEmailHomeLabel
#endif
- { "ADR", kABAddressProperty, &vCard2ABPerson::toPersonAddr, &vCard2ABPerson::fromPersonAddr, ADDRESSES },
+ { "ADR", &kABAddressProperty, &vCard2ABPerson::toPersonAddr, &vCard2ABPerson::fromPersonAddr, ADDRESSES },
#if 0
kABAddressWorkLabel
kABAddressHomeLabel
@@ -812,7 +970,9 @@ kABAddressCountryCodeKey
#endif
/* LABEL */
- { "TEL", kABPhoneProperty, &vCard2ABPerson::toPersonPhone, &vCard2ABPerson::fromPersonPhone, PHONES },
+ { "TEL", &kABPhoneProperty, &vCard2ABPerson::toPersonPhone, &vCard2ABPerson::fromPersonPhone, PHONES },
+#endif // __arm__
+
#if 0
kABPhoneWorkLabel
kABPhoneHomeLabel
@@ -822,18 +982,22 @@ kABPhoneHomeFAXLabel
kABPhoneWorkFAXLabel
kABPhonePagerLabel
#endif
- { "X-AIM", kABAIMInstantProperty, &vCard2ABPerson::toPersonStore, &vCard2ABPerson::fromPersonChat, AIM },
- { "X-JABBER", kABJabberInstantProperty, &vCard2ABPerson::toPersonStore, &vCard2ABPerson::fromPersonChat, JABBER },
- { "X-MSN", kABMSNInstantProperty, &vCard2ABPerson::toPersonStore, &vCard2ABPerson::fromPersonChat, MSN },
- { "X-YAHOO", kABYahooInstantProperty, &vCard2ABPerson::toPersonStore, &vCard2ABPerson::fromPersonChat, YAHOO },
- { "X-ICQ", kABICQInstantProperty, &vCard2ABPerson::toPersonStore, &vCard2ABPerson::fromPersonChat, ICQ },
+#ifndef __arm__
+ { "X-AIM", &kABAIMInstantProperty, &vCard2ABPerson::toPersonStore, &vCard2ABPerson::fromPersonChat, AIM },
+ { "X-JABBER", &kABJabberInstantProperty, &vCard2ABPerson::toPersonStore, &vCard2ABPerson::fromPersonChat, JABBER },
+ { "X-MSN", &kABMSNInstantProperty, &vCard2ABPerson::toPersonStore, &vCard2ABPerson::fromPersonChat, MSN },
+ { "X-YAHOO", &kABYahooInstantProperty, &vCard2ABPerson::toPersonStore, &vCard2ABPerson::fromPersonChat, YAHOO },
+ { "X-ICQ", &kABICQInstantProperty, &vCard2ABPerson::toPersonStore, &vCard2ABPerson::fromPersonChat, ICQ },
+#endif
/* "X-GROUPWISE */
- { "NOTE", kABNoteProperty },
- { "NICKNAME", kABNicknameProperty },
+ { "NOTE", &kABNoteProperty },
+ { "NICKNAME", &kABNicknameProperty },
/* kABMaidenNameProperty */
/* kABOtherDatesProperty */
- { "", kABRelatedNamesProperty, NULL, &vCard2ABPerson::fromPersonNames },
+#ifndef __arm__
+ { "", &kABRelatedNamesProperty, NULL, &vCard2ABPerson::fromPersonNames },
+#endif
#if 0
kABMotherLabel
kABFatherLabel
@@ -865,9 +1029,13 @@ kABManagerLabel
};
-
double AddressBookSource::getModTime(ABRecordRef record)
{
+ double absolute;
+#ifdef __arm__
+ absolute = (double)(int)ABRecordCopyValue(record,
+ kABModificationDateProperty);
+#else
ref<CFDateRef> itemModTime((CFDateRef)ABRecordCopyValue(record,
kABModificationDateProperty));
if (!itemModTime) {
@@ -877,12 +1045,13 @@ double AddressBookSource::getModTime(ABRecordRef record)
if (!itemModTime) {
throwError("cannot extract time stamp");
}
+ absolute = CFDateGetAbsoluteTime(itemModTime);
+#endif
// round up to next full second:
// together with a sleep of 1 second in endSyncThrow() this ensures
// that our time stamps are always >= the stored time stamp even if
// the time stamp is rounded in the database
- double absolute = CFDateGetAbsoluteTime(itemModTime);
return ceil(absolute);
}
@@ -912,7 +1081,10 @@ EvolutionSyncSource::sources AddressBookSource::getSyncBackends()
void AddressBookSource::open()
{
- m_addressbook.set(ABGetSharedAddressBook(), "address book");
+ m_addressbook = ABGetSharedAddressBook();
+ if (!m_addressbook) {
+ throwError("could not open address book");
+ }
m_modTimes.set(new spdm::DeviceManagementNode(m_modNodeName.c_str()), "change management node");
m_modTimes->setAutosave(FALSE);
}
@@ -976,37 +1148,60 @@ void AddressBookSource::endSyncThrow()
resetItems();
if (m_addressbook && !hasFailed()) {
+ LOG.debug("flushing address book");
+
// store changes persistently
if (!ABSave(m_addressbook)) {
throwError("could not save address book");
}
+
+ fprintf(stderr, "saved address book\n");
+
m_modTimes->update(FALSE);
// time stamps are rounded to next second,
// so to prevent changes in that range of inaccurracy
// sleep a bit before returning control
sleep(2);
+
+ LOG.debug("done with address book");
}
}
void AddressBookSource::close()
{
+ printf("close\n");
endSyncThrow();
+ printf("free addressbook\n");
m_addressbook = NULL;
+ printf("free mod times\n");
m_modTimes = NULL;
+ printf("closed\n");
}
void AddressBookSource::exportData(ostream &out)
{
+ LOG.debug("getting list of all people");
+
ref<CFArrayRef> allPersons(ABCopyArrayOfAllPeople(m_addressbook), "list of all people");
+ LOG.debug("got list");
+ LOG.debug("%d persons", (int)CFArrayGetCount(allPersons));
+
for (CFIndex i = 0; i < CFArrayGetCount(allPersons); i++) {
- ref<CFStringRef> cfuid(ABRecordCopyUniqueId((ABRecordRef)CFArrayGetValueAtIndex(allPersons, i)), "reading UID");
+ ABRecordRef person = (ABRecordRef)CFArrayGetValueAtIndex(allPersons, i);
+ CFStringRef descr = CFCopyDescription(person);
+ LOG.debug("at index foo %s", CFString2Std(descr).c_str());
+ LOG.debug("before copy");
+ ref<CFStringRef> cfuid(ABRecordCopyUniqueId(person), "reading UID");
+ LOG.debug("after copy");
string uid(CFString2Std(cfuid));
eptr<SyncItem> item(createItem(uid, SYNC_STATE_NONE), "sync item");
out << (char *)item->getData() << "\n";
}
+
+ LOG.debug("done with list of all people");
}
SyncItem *AddressBookSource::createItem( const string &uid, SyncState state )
@@ -1074,7 +1269,9 @@ int AddressBookSource::insertItem(SyncItem &item, const char *uid)
person.set((ABPersonRef)ABCopyRecordForUniqueId(m_addressbook, cfuid), "contact");
} else {
// new contact
- person.set(ABPersonCreate(), "contact");
+ LOG.debug("before creating contact");
+ person.set(PersonCreateWrapper(m_addressbook), "contact");
+ LOG.debug("after creating contact");
}
try {
LOG.debug("storing vCard for %s:\n%s",
@@ -1082,6 +1279,7 @@ int AddressBookSource::insertItem(SyncItem &item, const char *uid)
data.c_str());
vCard2ABPerson converter(data, person);
converter.toPerson();
+ LOG.debug("person set");
} catch (const std::exception &ex) {
throwError(string("storing vCard for ") + (uid ? uid : "new contact") + " failed: " + ex.what());
}
@@ -1090,22 +1288,39 @@ int AddressBookSource::insertItem(SyncItem &item, const char *uid)
// make sure we have a modification time stamp, otherwise the address book
// sets one at random times
+ LOG.debug("create time");
CFAbsoluteTime nowabs = CFAbsoluteTimeGetCurrent();
+ LOG.debug("setting absolute time %f", nowabs);
+#ifdef __arm__
+ void *now = (void *)(int)round(nowabs);
+#else
ref<CFDateRef> now(CFDateCreate(NULL, nowabs), "current time");
+#endif
if (!ABRecordSetValue(person, kABModificationDateProperty, now)) {
throwError("setting mod time");
}
+ LOG.debug("time set\n");
// existing contacts do not have to (and cannot) be added (?)
if (uid || ABAddRecord(m_addressbook, person)) {
+ printf("inserted contact\n");
+
+#ifdef __arm__
+ /* need to save to get UID? */
+ ABSave(m_addressbook);
+#endif
+
ref<CFStringRef> cfuid(ABRecordCopyUniqueId(person), "uid");
- string uid(CFString2Std(cfuid));
- item.setKey(uid.c_str());
+ string uidstr(CFString2Std(cfuid));
+ item.setKey(uidstr.c_str());
char buffer[80];
sprintf(buffer, "%.8f", getModTime(person));
- m_modTimes->setPropertyValue(uid.c_str(), buffer);
+ LOG.debug("inserted contact %s with modification time %s",
+ uidstr.c_str(), buffer);
+ m_modTimes->setPropertyValue(uidstr.c_str(), buffer);
} else {
+ printf("error adding contact\n");
throwError("storing new contact");
}
diff --git a/src/AddressBookSource.h b/src/AddressBookSource.h
index f2e18a93..048d8b27 100644
--- a/src/AddressBookSource.h
+++ b/src/AddressBookSource.h
@@ -71,6 +71,7 @@ template<class T> class ref {
*/
void set( T pointer, const char *objectName = NULL )
{
+ fprintf(stderr, "ref %p: %p -> %p\n", this, m_pointer, pointer);
if (m_pointer) {
CFRelease(m_pointer);
}
@@ -155,7 +156,7 @@ class AddressBookSource : public EvolutionSyncSource
private:
/** valid after open(): the address book that this source references */
- ref<ABAddressBookRef> m_addressbook;
+ ABAddressBookRef m_addressbook;
/**
* Stores the modification time of all items sent to or received from the server.