2007-08-19 21:11:20 +02:00
|
|
|
/*
|
2008-08-26 19:45:28 +02:00
|
|
|
* Copyright (C) 2007-2008 Patrick Ohly
|
2007-08-19 21:11:20 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef INCL_ADDRESSBOOKSOURCE
|
|
|
|
#define INCL_ADDRESSBOOKSOURCE
|
|
|
|
|
|
|
|
#include <config.h>
|
2008-07-12 21:31:03 +02:00
|
|
|
#include "TrackingSyncSource.h"
|
2007-08-19 21:11:20 +02:00
|
|
|
|
|
|
|
#ifdef ENABLE_ADDRESSBOOK
|
|
|
|
|
|
|
|
#include <AddressBook/ABAddressBookC.h>
|
|
|
|
|
|
|
|
/**
|
2007-10-07 14:19:14 +02:00
|
|
|
* a smart pointer for CoreFoundation object references
|
2007-08-19 21:11:20 +02:00
|
|
|
*
|
|
|
|
* trying to store a NULL pointer raises an exception,
|
|
|
|
* unreferencing valid objects is done automatically
|
2007-10-07 14:19:14 +02:00
|
|
|
*
|
|
|
|
* @param T the pointer type
|
|
|
|
* @param release CFRelease() is only called when passing true
|
2007-08-19 21:11:20 +02:00
|
|
|
*/
|
2007-10-07 21:06:01 +02:00
|
|
|
template<class T, bool doRelease =
|
|
|
|
#ifdef IPHONE
|
|
|
|
// by default do not release anything because that has led
|
|
|
|
// to crashes: this is the safe default in case of doubt
|
|
|
|
false
|
|
|
|
#else
|
|
|
|
true
|
|
|
|
#endif
|
|
|
|
> class ref {
|
2007-08-19 21:11:20 +02:00
|
|
|
/** do not allow copy construction */
|
|
|
|
ref( const ref &other) {};
|
|
|
|
|
|
|
|
/** do not allow copying */
|
|
|
|
void operator = ( const ref &other ) {}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
T m_pointer;
|
|
|
|
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* create a smart pointer that owns the given object;
|
|
|
|
* passing a NULL pointer and a name for the object raises an error
|
|
|
|
*/
|
|
|
|
ref(T pointer = NULL, const char *objectName = NULL) :
|
|
|
|
m_pointer( pointer )
|
|
|
|
{
|
|
|
|
if (!pointer && objectName ) {
|
|
|
|
throw std::runtime_error(std::string("Error allocating ") + objectName);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
~ref()
|
|
|
|
{
|
|
|
|
set( NULL );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* store another object in this pointer, replacing any which was
|
|
|
|
* referenced there before;
|
|
|
|
* passing a NULL pointer and a name for the object raises an error
|
|
|
|
*/
|
|
|
|
void set( T pointer, const char *objectName = NULL )
|
|
|
|
{
|
2007-10-07 14:19:14 +02:00
|
|
|
if (m_pointer && doRelease) {
|
2007-08-19 21:11:20 +02:00
|
|
|
CFRelease(m_pointer);
|
|
|
|
}
|
|
|
|
if (!pointer && objectName) {
|
|
|
|
throw std::runtime_error(std::string("Error allocating ") + objectName);
|
|
|
|
}
|
|
|
|
m_pointer = pointer;
|
|
|
|
}
|
|
|
|
|
|
|
|
ref<T> &operator = ( T pointer ) { set( pointer ); return *this; }
|
|
|
|
T operator-> () { return m_pointer; }
|
|
|
|
T operator * () { return m_pointer; }
|
|
|
|
operator T () { return m_pointer; }
|
|
|
|
operator bool () { return m_pointer != NULL; }
|
2007-08-24 23:27:42 +02:00
|
|
|
|
|
|
|
T release() {
|
|
|
|
T res = m_pointer;
|
|
|
|
m_pointer = NULL;
|
|
|
|
return res;
|
|
|
|
}
|
2007-08-19 21:11:20 +02:00
|
|
|
};
|
|
|
|
|
2007-10-07 14:19:14 +02:00
|
|
|
#if 0
|
|
|
|
/* template typedefs would have been handy here, but are not specified in C++ (yet) */
|
|
|
|
#ifdef IPHONE
|
|
|
|
/** do not free some particular objects on the iPhone because that crashes */
|
|
|
|
template<class T> typedef ref<T, false> iphoneref;
|
|
|
|
#else
|
|
|
|
template<class T> typedef ref<T, true> iphoneref;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
#ifdef IPHONE
|
|
|
|
# define IPHONE_RELEASE false
|
|
|
|
#else
|
|
|
|
# define IPHONE_RELEASE true
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2007-08-19 21:11:20 +02:00
|
|
|
|
|
|
|
/**
|
2007-10-07 14:19:14 +02:00
|
|
|
* The AddressBookSource synchronizes the Mac OS X and iPhone system
|
|
|
|
* address book using the "AddressBook" framework. Changes are tracked
|
|
|
|
* by comparing the current time stamp of a contact against its time
|
|
|
|
* stamp from the previous sync, stored in a separate key/value
|
2007-10-14 16:02:15 +02:00
|
|
|
* database. Contacts are converted to/from vCard 2.1 using custom
|
2007-10-07 14:19:14 +02:00
|
|
|
* code because a) the mapping can be chosen so that typical SyncML
|
|
|
|
* servers understand it and b) the iPhone's AddressBook does not have
|
|
|
|
* vcard import/export functions.
|
|
|
|
*
|
|
|
|
* On the iPhone the interface is similar, but not the same. These
|
|
|
|
* differences are hidden behind "ifdef IPHONE" which depends (for
|
|
|
|
* simplicity reasons) on the __arm__ define.
|
|
|
|
*
|
|
|
|
* Some of the differences and how they are handled are listed here.
|
|
|
|
* - ABC instead of AB prefix, other renames: map Mac OS X name to iPhone
|
|
|
|
* name before including AddressBook.h, then use Mac OS X names
|
|
|
|
* - CFRelease() and CFCopyDescription on ABMultiValueRef crash (bugs?!):
|
|
|
|
* use ref<T, IPHONE_RELEASE> for those instead the normal ref smart pointer,
|
|
|
|
* avoid CFCopyDescription()
|
|
|
|
* - UID is integer, not CFStringRef: added wrapper function
|
|
|
|
* - the address of kABC*Property identifies properties, not the CFStringRef
|
|
|
|
* at that address, caused toolchain problems when initializing data
|
|
|
|
* with these addresses: added one additional address indirection
|
|
|
|
* - UIDs are assigned to added contacts only during saving, but are needed
|
|
|
|
* earlier: save after adding each contact (affects performance and aborted
|
|
|
|
* sync changes address book - perhaps better guess UID?)
|
|
|
|
* - Mac OS X 10.4 still uses the kABHomePageProperty (a single string),
|
|
|
|
* the iPhone switched to the more recent kABCURLProperty/kABURLsProperty:
|
|
|
|
* conversion code is slightly different
|
|
|
|
* - iPhone does not have a title (e.g. "sir") property, only the job title
|
|
|
|
* - label constants are not part of the framework:
|
|
|
|
* defined in AddressSourceConstants
|
2007-08-19 21:11:20 +02:00
|
|
|
*/
|
2008-07-12 21:31:03 +02:00
|
|
|
class AddressBookSource : public TrackingSyncSource
|
2007-08-19 21:11:20 +02:00
|
|
|
{
|
2008-07-12 21:31:03 +02:00
|
|
|
public:
|
2008-03-10 23:45:36 +01:00
|
|
|
AddressBookSource(const EvolutionSyncSourceParams ¶ms, bool asVCard30);
|
2007-08-19 21:11:20 +02:00
|
|
|
virtual ~AddressBookSource() { close(); }
|
|
|
|
|
2007-11-04 22:10:51 +01:00
|
|
|
void setVCard30(bool asVCard30) { m_asVCard30 = asVCard30; }
|
|
|
|
bool getVCard30() { return m_asVCard30; }
|
|
|
|
|
2008-07-10 21:17:42 +02:00
|
|
|
virtual Databases getDatabases();
|
2007-08-19 21:11:20 +02:00
|
|
|
virtual void open();
|
2008-07-12 21:31:03 +02:00
|
|
|
virtual void listAllItems(RevisionMap_t &revisions);
|
2007-08-19 21:11:20 +02:00
|
|
|
virtual void exportData(ostream &out);
|
2008-07-12 21:31:03 +02:00
|
|
|
virtual InsertItemResult insertItem(const string &uid, const SyncItem &item);
|
2008-01-13 02:41:21 +01:00
|
|
|
virtual SyncItem *createItem(const string &uid) { return createItem(uid, m_asVCard30); }
|
|
|
|
virtual SyncItem *createItem(const string &uid, bool asVCard30);
|
2008-07-12 21:31:03 +02:00
|
|
|
virtual void deleteItem(const string &uid);
|
|
|
|
virtual void flush() {}
|
|
|
|
virtual void close();
|
|
|
|
|
|
|
|
virtual string fileSuffix() const { return "vcf"; }
|
|
|
|
virtual const char *getMimeType() const { return m_asVCard30 ? "text/vcard" : "text/x-vcard"; }
|
|
|
|
virtual const char *getMimeVersion() const { return m_asVCard30 ? "3.0" : "2.1"; }
|
|
|
|
virtual const char *getSupportedTypes() const { return m_asVCard30 ? "text/vcard:3.0" : "text/x-vcard:2.1"; }
|
|
|
|
|
|
|
|
protected:
|
2007-08-19 21:11:20 +02:00
|
|
|
virtual void logItem(const string &uid, const string &info, bool debug = false);
|
2008-04-07 19:59:17 +02:00
|
|
|
virtual void logItem(const SyncItem &item, const string &info, bool debug = false);
|
2007-08-19 21:11:20 +02:00
|
|
|
|
2007-08-21 22:15:32 +02:00
|
|
|
|
2007-08-19 21:11:20 +02:00
|
|
|
private:
|
|
|
|
/** valid after open(): the address book that this source references */
|
2007-10-04 22:54:27 +02:00
|
|
|
ABAddressBookRef m_addressbook;
|
2007-08-21 22:15:32 +02:00
|
|
|
|
|
|
|
/** returns absolute modification time or (if that doesn't exist) the creation time */
|
2008-07-12 21:31:03 +02:00
|
|
|
string getModTime(ABRecordRef record);
|
2007-11-04 22:10:51 +01:00
|
|
|
|
|
|
|
/** unless selected otherwise send items as vCard 2.1 */
|
|
|
|
bool m_asVCard30;
|
2007-08-19 21:11:20 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // ENABLE_EBOOK
|
|
|
|
|
|
|
|
#endif // INCL_ADDRESSBOOKSOURCE
|