diff options
author | Patrick Ohly <patrick.ohly@intel.com> | 2009-02-17 12:18:15 +0100 |
---|---|---|
committer | Patrick Ohly <patrick.ohly@gmx.de> | 2009-03-25 14:43:35 +0100 |
commit | 43f2c5fec5666dd747ac36c74085b82e6cd01493 (patch) | |
tree | 3f80f6b9f288fd8ca1ea714a0b5071bfc0774d93 | |
parent | d801974f74742cdee08c8884c65762ac87c84439 (diff) |
removed all references to Funambol header files and definitions
32 files changed, 514 insertions, 2130 deletions
@@ -58,18 +58,15 @@ Funambol client library or non-default sources - see the "funambol" configure options for details. For doing development work the recommended configure line is: - configure SYNCEVOLUTION_CXXFLAGS="-Wall -Werror -Wno-unknown-pragmas" \ + configure CXXFLAGS="-Wall -Werror -Wno-unknown-pragmas" \ --enable-unit-tests \ --enable-libcurl Enabling libcurl explicitly ensures that it gets built even when not the default. -In contrast to CXXFLAGS, SYNCEVOLUTION_CXXFLAGS adds these flags only -to the compilation of source files from the SyncEvolution source code -repository, but not the client library. -Wno-unknown-pragmas is -required to avoid warnings triggered by '#pragma }', a trick to -preserve indention after 'extern "C" {' in +-Wno-unknown-pragmas is required to avoid warnings triggered by +'#pragma }', a trick to preserve indention after 'extern "C" {' in /usr/include/evolution-data-server-1.12/libical/ Working with the Code @@ -220,7 +217,7 @@ Compiling for Mac OS X Configuring for development: <path>/configure --with-funambol-src=<path> \ --enable-addressbook \ - SYNCEVOLUTION_CXXFLAGS="-Wall -Werror -Wno-unknown-pragmas" \ + CXXFLAGS="-Wall -Werror -Wno-unknown-pragmas" \ LDFLAGS="-framework Addressbook -framework CoreServices" \ CXXFLAGS=-g \ CFLAGS=-g diff --git a/configure-pre.in b/configure-pre.in index 8fd96e02..1eb67fc7 100644 --- a/configure-pre.in +++ b/configure-pre.in @@ -32,36 +32,36 @@ else FUNAMBOLSRC_DEF="FUNAMBOLSRC_REPO" fi -AC_ARG_WITH(funambol-src, - AS_HELP_STRING([--with-funambol-src=<base directory|svn URL|git URL>], - [Specifies location of the Funambol 'client-api/native' source code. - Use this instead of --with-funambol when the client library is to - be compiled as part of the SyncEvolution compilation. In release - versions of SyncEvolution, a copy of the client library is bundled - under 'src/client-api' and compiled unless something else is - specified. --with-funambol-src can be given a path to sources - checked out already, a Subversion repository URL or a git repository - URL. When given a repository URL, then the configure script - will checkout the sources into 'src/client-api-copy' or - update that working copy if the directory already exists. - Default: bundled source in src/client-api (in released SyncEvolution sources), - FUNAMBOLSRC_REPO otherwise.]), - [FUNAMBOLSRC="$withval"], [FUNAMBOLSRC="$FUNAMBOLSRC_DEF"; REVISION="FUNAMBOLSRC_REVISION"]) - -AC_ARG_WITH(sync4j-src, - AS_HELP_STRING([--with-sync4j-src=<base directory>], - [alias for --with-funambol-src]), - [FUNAMBOLSRC="$withval"]) - -AC_ARG_WITH(funambol-username, - AS_HELP_STRING([--with-funambol-username=<svn username>], - [username to use when checking out --with-funambol-src sources from Subversion, default 'guest']), - [USERNAME="$withval"], [USERNAME="guest"]) - -AC_ARG_WITH(funambol-revision, - AS_HELP_STRING([--with-funambol-revision=<git tag/branch/hash or Subversion revision>], - [Identifies which source revision to use from --with-funambol-src repository, empty string stands for latest. Default for default --funambol-src: FUNAMBOLSRC_REVISION]), - [REVISION="$withval"]) +dnl AC_ARG_WITH(funambol-src, +dnl AS_HELP_STRING([--with-funambol-src=<base directory|svn URL|git URL>], +dnl [Specifies location of the Funambol 'client-api/native' source code. +dnl Use this instead of --with-funambol when the client library is to +dnl be compiled as part of the SyncEvolution compilation. In release +dnl versions of SyncEvolution, a copy of the client library is bundled +dnl under 'src/client-api' and compiled unless something else is +dnl specified. --with-funambol-src can be given a path to sources +dnl checked out already, a Subversion repository URL or a git repository +dnl URL. When given a repository URL, then the configure script +dnl will checkout the sources into 'src/client-api-copy' or +dnl update that working copy if the directory already exists. +dnl Default: bundled source in src/client-api (in released SyncEvolution sources), +dnl FUNAMBOLSRC_REPO otherwise.]), +dnl [FUNAMBOLSRC="$withval"], [FUNAMBOLSRC="$FUNAMBOLSRC_DEF"; REVISION="FUNAMBOLSRC_REVISION"]) + +dnl AC_ARG_WITH(sync4j-src, +dnl AS_HELP_STRING([--with-sync4j-src=<base directory>], +dnl [alias for --with-funambol-src]), +dnl [FUNAMBOLSRC="$withval"]) + +dnl AC_ARG_WITH(funambol-username, +dnl AS_HELP_STRING([--with-funambol-username=<svn username>], +dnl [username to use when checking out --with-funambol-src sources from Subversion, default 'guest']), +dnl [USERNAME="$withval"], [USERNAME="guest"]) + +dnl AC_ARG_WITH(funambol-revision, +dnl AS_HELP_STRING([--with-funambol-revision=<git tag/branch/hash or Subversion revision>], +dnl [Identifies which source revision to use from --with-funambol-src repository, empty string stands for latest. Default for default --funambol-src: FUNAMBOLSRC_REVISION]), +dnl [REVISION="$withval"]) AC_ARG_ENABLE(shared, AS_HELP_STRING([--enable-shared], @@ -136,7 +136,7 @@ AC_SUBST(CORE_LDADD_DEP) # preserve src/client-api by default, # always CLEAN_CLIENT_SRC= -FUNAMBOL_LIB=$PWD/src/build-client-api/src/libfunambol.la +dnl FUNAMBOL_LIB=$PWD/src/build-client-api/src/libfunambol.la AC_SUBST(CLEAN_CLIENT_SRC) @@ -216,115 +216,117 @@ AC_SUBST(TRANSPORT_LIBS) AC_SUBST(TRANSPORT_CFLAGS) -# absolute patch to source of Funambol client library -CLIENT_API_SRC=no-client-api-source -AC_SUBST(CLIENT_API_SRC) -if test ! "$FUNAMBOL"; then - if test "$FUNAMBOLSRC"; then - # default: checkout a copy of the sources, remove it during maintainer-clean and distclean - CLEAN_CLIENT_SRC=client-api-copy - CLIENT_API_SRC=$PWD/src/client-api-copy - - AC_MSG_NOTICE( [updating the content of $CLIENT_API_SRC from $FUNAMBOLSRC] ) - case "$FUNAMBOLSRC" in - *://*) protocol="`echo $FUNAMBOLSRC | sed -e 's;://.*;;'`";; - *) protocol="file";; - esac - - mkdir -p src - case $protocol in - file) - # use existing copy of the sources - CLEAN_CLIENT_SRC= - case "$FUNAMBOLSRC" in - /*) CLIENT_API_SRC="$FUNAMBOLSRC";; - *) CLIENT_API_SRC="$PWD/$FUNAMBOLSRC";; - esac - ;; - *svn*|*http*) - FUNAMBOLSRCREV="$FUNAMBOLSRC" - if test "$REVISION"; then - revarg="-r $REVISION " - if `echo $FUNAMBOLSRC | grep '@[0123456789]*'` >/dev/null; then - : - else - FUNAMBOLSRCREV="$FUNAMBOLSRC@$REVISION" - fi - fi - if test -d $CLIENT_API_SRC ; then - ( set -x; cd $CLIENT_API_SRC && svn --username=$USERNAME switch $revarg "$FUNAMBOLSRC" ) || AC_ERROR([updating from $FUNAMBOLSRC failed]) - else - (set -x; svn --username=$USERNAME checkout $revarg "$FUNAMBOLSRCREV" $CLIENT_API_SRC ) || AC_ERROR([checking out $FUNAMBOLSRC failed]) - fi - ;; - *git*) - if test -d $CLIENT_API_SRC ; then - ( set -x; cd $CLIENT_API_SRC && git fetch "$FUNAMBOLSRC" ) || AC_ERROR([updating from $FUNAMBOLSRC failed]) - else - ( set -x; git clone "$FUNAMBOLSRC" $CLIENT_API_SRC ) || AC_ERROR([cloning $FUNAMBOLSRC failed]) - fi - if test "$REVISION"; then - # git 1.6 finds tags and branches without explicit prefix, 1.4.4.4 doesn't - ( set -x; cd $CLIENT_API_SRC && - (git checkout "$REVISION" || - git checkout "tags/$REVISION" || - git checkout "origin/$REVISION") ) || AC_ERROR([checking out $FUNAMBOLSRC failed]) - fi - ;; - esac - else - # use existing copy of the sources; beware of - # out-of-tree compilation - case $srcdir in - /*) CLIENT_API_SRC="$srcdir/src/client-api";; - *) CLIENT_API_SRC="$PWD/$srcdir/src/client-api";; - esac - fi - - ( cd $CLIENT_API_SRC/build/autotools && ( test -f configure || sh autogen.sh ) ) - - if test -f $CLIENT_API_SRC/build/autotools/configure; then - CLIENT_CONFIGURE="$CLIENT_API_SRC/build/autotools/configure" - chmod u+x $CLIENT_API_SRC/build/autotools/configure $CLIENT_API_SRC/build/autotools/config.sub $CLIENT_API_SRC/build/autotools/config.guess - - # use local copy of the sources, with dependencies - # to trigger building the client library - FUNAMBOL_SUBDIR=$PWD/src/build-client-api - FUNAMBOL_DEP=$PWD/src/build-client-api/src/libfunambol.la - - FUNAMBOL_CFLAGS="-I$FUNAMBOL_SUBDIR/include/posix -I$FUNAMBOL_SUBDIR/include/common -I$FUNAMBOL_SUBDIR/include -I$FUNAMBOL_SUBDIR/test" - FUNAMBOL_LIBS="-L$FUNAMBOL_SUBDIR/src -lfunambol" - - AC_MSG_NOTICE( [configuring the client library] ) - # Passing some specific configure arguments to the client library's - # configure makes sense (e.g., --enable-unit-tests) or is - # required (--disable-dependency-tracking when compiling for - # multiple architectures on Mac OS X). - cxx_lib_args=`for i in --disable-dependency-tracking --enable-unit-tests; do - if echo $ac_configure_args | grep -e $i >/dev/null; then - echo $i; - fi; - done` - if test "$enable_shared" == "yes"; then - # Okay, this is a shortcut: strictly speaking we would have - # to check with autoconf for the right flags... - FUNAMBOL_LIB_SHARED_FLAGS="-DPIC -fPIC" - fi - if (set -x; mkdir -p $FUNAMBOL_SUBDIR && cd $FUNAMBOL_SUBDIR && $CLIENT_CONFIGURE $CLIENT_CONFIGURE_OPTIONS --build=$build_alias --host=$host_alias --target=$target_alias --disable-shared --with-transport-agent=curl CFLAGS="$CFLAGS $FUNAMBOL_LIB_SHARED_FLAGS" CXXFLAGS="$CXXFLAGS $FUNAMBOL_LIB_SHARED_FLAGS" $cxx_lib_args); then true; else - AC_MSG_ERROR( [configuring client library failed] ) - fi - else - AC_MSG_ERROR( [either --with-funambol or --with-funambol-src have to be used] ) - fi -else - if test -f $FUNAMBOL/include/funambol/common/spds/SyncItem.h; then - FUNAMBOL_CFLAGS="-I$FUNAMBOL/include/funambol/posix -I$FUNAMBOL/include/funambol/common -I$FUNAMBOL/include/funambol" - FUNAMBOL_LIBS="-L$FUNAMBOL/lib -lfunambol" - else - AC_MSG_ERROR( [$FUNAMBOL does seem to be valid (e.g. include/funambol/spds/common/SyncItem.h is missing)] ) - fi -fi - +dnl # absolute patch to source of Funambol client library +dnl CLIENT_API_SRC=no-client-api-source +dnl AC_SUBST(CLIENT_API_SRC) +dnl if test ! "$FUNAMBOL"; then +dnl if test "$FUNAMBOLSRC"; then +dnl # default: checkout a copy of the sources, remove it during maintainer-clean and distclean +dnl CLEAN_CLIENT_SRC=client-api-copy +dnl CLIENT_API_SRC=$PWD/src/client-api-copy + +dnl AC_MSG_NOTICE( [updating the content of $CLIENT_API_SRC from $FUNAMBOLSRC] ) +dnl case "$FUNAMBOLSRC" in +dnl *://*) protocol="`echo $FUNAMBOLSRC | sed -e 's;://.*;;'`";; +dnl *) protocol="file";; +dnl esac + +dnl mkdir -p src +dnl case $protocol in +dnl file) +dnl # use existing copy of the sources +dnl CLEAN_CLIENT_SRC= +dnl case "$FUNAMBOLSRC" in +dnl /*) CLIENT_API_SRC="$FUNAMBOLSRC";; +dnl *) CLIENT_API_SRC="$PWD/$FUNAMBOLSRC";; +dnl esac +dnl ;; +dnl *svn*|*http*) +dnl FUNAMBOLSRCREV="$FUNAMBOLSRC" +dnl if test "$REVISION"; then +dnl revarg="-r $REVISION " +dnl if `echo $FUNAMBOLSRC | grep '@[0123456789]*'` >/dev/null; then +dnl : +dnl else +dnl FUNAMBOLSRCREV="$FUNAMBOLSRC@$REVISION" +dnl fi +dnl fi +dnl if test -d $CLIENT_API_SRC ; then +dnl ( set -x; cd $CLIENT_API_SRC && svn --username=$USERNAME switch $revarg "$FUNAMBOLSRC" ) || AC_ERROR([updating from $FUNAMBOLSRC failed]) +dnl else +dnl (set -x; svn --username=$USERNAME checkout $revarg "$FUNAMBOLSRCREV" $CLIENT_API_SRC ) || AC_ERROR([checking out $FUNAMBOLSRC failed]) +dnl fi +dnl ;; +dnl *git*) +dnl if test -d $CLIENT_API_SRC ; then +dnl ( set -x; cd $CLIENT_API_SRC && git fetch "$FUNAMBOLSRC" ) || AC_ERROR([updating from $FUNAMBOLSRC failed]) +dnl else +dnl ( set -x; git clone "$FUNAMBOLSRC" $CLIENT_API_SRC ) || AC_ERROR([cloning $FUNAMBOLSRC failed]) +dnl fi +dnl if test "$REVISION"; then +dnl # git 1.6 finds tags and branches without explicit prefix, 1.4.4.4 doesn't +dnl ( set -x; cd $CLIENT_API_SRC && +dnl (git checkout "$REVISION" || +dnl git checkout "tags/$REVISION" || +dnl git checkout "origin/$REVISION") ) || AC_ERROR([checking out $FUNAMBOLSRC failed]) +dnl fi +dnl ;; +dnl esac +dnl else +dnl # use existing copy of the sources; beware of +dnl # out-of-tree compilation +dnl case $srcdir in +dnl /*) CLIENT_API_SRC="$srcdir/src/client-api";; +dnl *) CLIENT_API_SRC="$PWD/$srcdir/src/client-api";; +dnl esac +dnl fi + +dnl ( cd $CLIENT_API_SRC/build/autotools && ( test -f configure || sh autogen.sh ) ) + +dnl if test -f $CLIENT_API_SRC/build/autotools/configure; then +dnl CLIENT_CONFIGURE="$CLIENT_API_SRC/build/autotools/configure" +dnl chmod u+x $CLIENT_API_SRC/build/autotools/configure $CLIENT_API_SRC/build/autotools/config.sub $CLIENT_API_SRC/build/autotools/config.guess + +dnl # use local copy of the sources, with dependencies +dnl # to trigger building the client library +dnl FUNAMBOL_SUBDIR=$PWD/src/build-client-api +dnl FUNAMBOL_DEP=$PWD/src/build-client-api/src/libfunambol.la + +dnl FUNAMBOL_CFLAGS="-I$FUNAMBOL_SUBDIR/include/posix -I$FUNAMBOL_SUBDIR/include/common -I$FUNAMBOL_SUBDIR/include -I$FUNAMBOL_SUBDIR/test" +dnl FUNAMBOL_LIBS="-L$FUNAMBOL_SUBDIR/src -lfunambol" + +dnl AC_MSG_NOTICE( [configuring the client library] ) +dnl # Passing some specific configure arguments to the client library's +dnl # configure makes sense (e.g., --enable-unit-tests) or is +dnl # required (--disable-dependency-tracking when compiling for +dnl # multiple architectures on Mac OS X). +dnl cxx_lib_args=`for i in --disable-dependency-tracking --enable-unit-tests; do +dnl if echo $ac_configure_args | grep -e $i >/dev/null; then +dnl echo $i; +dnl fi; +dnl done` +dnl if test "$enable_shared" == "yes"; then +dnl # Okay, this is a shortcut: strictly speaking we would have +dnl # to check with autoconf for the right flags... +dnl FUNAMBOL_LIB_SHARED_FLAGS="-DPIC -fPIC" +dnl fi +dnl if (set -x; mkdir -p $FUNAMBOL_SUBDIR && cd $FUNAMBOL_SUBDIR && $CLIENT_CONFIGURE $CLIENT_CONFIGURE_OPTIONS --build=$build_alias --host=$host_alias --target=$target_alias --disable-shared --with-transport-agent=curl CFLAGS="$CFLAGS $FUNAMBOL_LIB_SHARED_FLAGS" CXXFLAGS="$CXXFLAGS $FUNAMBOL_LIB_SHARED_FLAGS" $cxx_lib_args); then true; else +dnl AC_MSG_ERROR( [configuring client library failed] ) +dnl fi +dnl else +dnl AC_MSG_ERROR( [either --with-funambol or --with-funambol-src have to be used] ) +dnl fi +dnl else +dnl if test -f $FUNAMBOL/include/funambol/common/spds/SyncItem.h; then +dnl FUNAMBOL_CFLAGS="-I$FUNAMBOL/include/funambol/posix -I$FUNAMBOL/include/funambol/common -I$FUNAMBOL/include/funambol" +dnl FUNAMBOL_LIBS="-L$FUNAMBOL/lib -lfunambol" +dnl else +dnl AC_MSG_ERROR( [$FUNAMBOL does seem to be valid (e.g. include/funambol/spds/common/SyncItem.h is missing)] ) +dnl fi +dnl fi + +dnl TODO: compile Synthesis library the same way Funambol was compiled/bundled before? +dnl Makefiles are unchanged for that purpose. FUNAMBOL_CFLAGS="$FUNAMBOL_CFLAGS $SYNTHESIS_CFLAGS" AC_SUBST(FUNAMBOL_CFLAGS) diff --git a/src/Makefile-gen.am b/src/Makefile-gen.am index 62732dae..f22c110e 100644 --- a/src/Makefile-gen.am +++ b/src/Makefile-gen.am @@ -118,12 +118,13 @@ distclean-local: # executed. The workaround is to explicitly set them as undefined on the # link line. client_test_SOURCES = client-test-app.cpp $(CORE_SOURCES) -CLIENT_LIB_TEST_FILES = ClientTest.h ClientTest.cpp client-test-main.cpp \ - testcases/vcard21.vcf \ - testcases/vcard30.vcf \ - testcases/ical20.ics \ - testcases/imemo20.ics \ - testcases/itodo20.ics +CLIENT_LIB_TEST_FILES = +# ClientTest.h ClientTest.cpp client-test-main.cpp \ +# testcases/vcard21.vcf \ +# testcases/vcard30.vcf \ +# testcases/ical20.ics \ +# testcases/imemo20.ics \ +# testcases/itodo20.ics nodist_client_test_SOURCES = $(CLIENT_LIB_TEST_FILES) client_test_CPPFLAGS = -DHAVE_CONFIG_H -DENABLE_INTEGRATION_TESTS -DENABLE_UNIT_TESTS $(AM_CPPFLAGS) client_test_CXXFLAGS = `cppunit-config --cflags` $(SYNCEVOLUTION_CXXFLAGS) diff --git a/src/backends/evolution/EvolutionCalendarSource.cpp b/src/backends/evolution/EvolutionCalendarSource.cpp index ad690dbf..4b85b817 100644 --- a/src/backends/evolution/EvolutionCalendarSource.cpp +++ b/src/backends/evolution/EvolutionCalendarSource.cpp @@ -229,24 +229,12 @@ SyncItem *EvolutionCalendarSource::createItem(const string &luid) ItemID id(luid); string icalstr = retrieveItemAsString(id); - auto_ptr<SyncItem> item(new SyncItem(luid.c_str())); + cxxptr<SyncItem> item(new SyncItem(), "SyncItem"); + item->setKey(luid); item->setData(icalstr.c_str(), icalstr.size()); - item->setDataType("text/calendar"); - item->setModificationTime(0); - return item.release(); } -void EvolutionCalendarSource::setItemStatusThrow(const char *key, int status) -{ - switch (status) { - case STC_CONFLICT_RESOLVED_WITH_SERVER_DATA: - SE_LOG_ERROR(this, NULL, "item %.80s: conflict, will be replaced by server\n", key); - break; - } - TrackingSyncSource::setItemStatusThrow(key, status); -} - EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(const string &luid, const SyncItem &item) { bool update = !luid.empty(); @@ -584,9 +572,8 @@ static string extractProp(const char *data, const char *keyword) void EvolutionCalendarSource::logItem(const SyncItem &item, const string &info, bool debug) { if (getLevel() >= (debug ? Logger::DEBUG : Logger::INFO)) { - const char *keyptr = item.getKey(); - string key; - if (!keyptr || !keyptr[0]) { + string key = item.getKey(); + if (key.empty()) { // get UID from data via simple string search; doesn't have to be perfect const char *data = (const char *)item.getData(); string uid = extractProp(data, "\nUID:"); @@ -596,8 +583,6 @@ void EvolutionCalendarSource::logItem(const SyncItem &item, const string &info, } else { key = ItemID::getLUID(uid, rid); } - } else { - key = keyptr; } SE_LOG(debug ? Logger::DEBUG : Logger::INFO, this, NULL, "%s: %s", key.c_str(), info.c_str()); } diff --git a/src/backends/evolution/EvolutionCalendarSource.h b/src/backends/evolution/EvolutionCalendarSource.h index 23cc79cb..e5af0cb0 100644 --- a/src/backends/evolution/EvolutionCalendarSource.h +++ b/src/backends/evolution/EvolutionCalendarSource.h @@ -53,7 +53,6 @@ class EvolutionCalendarSource : public TrackingSyncSource // virtual void listAllItems(RevisionMap_t &revisions); virtual InsertItemResult insertItem(const string &luid, const SyncItem &item); - virtual void setItemStatusThrow(const char *key, int status); virtual void deleteItem(const string &luid); virtual void logItem(const string &luid, const string &info, bool debug = false); virtual void logItem(const SyncItem &item, const string &info, bool debug = false); diff --git a/src/backends/evolution/EvolutionContactSource.cpp b/src/backends/evolution/EvolutionContactSource.cpp index f3e7152f..866eca84 100644 --- a/src/backends/evolution/EvolutionContactSource.cpp +++ b/src/backends/evolution/EvolutionContactSource.cpp @@ -18,8 +18,6 @@ using namespace std; #include "SyncEvolutionUtil.h" #include "Logging.h" -#include "vocl/VConverter.h" -using namespace vocl; #include <boost/algorithm/string.hpp> #include <boost/foreach.hpp> @@ -331,27 +329,29 @@ void EvolutionContactSource::exportData(ostream &out) } } -SyncItem *EvolutionContactSource::createItem(const string &uid) +SyncItem *EvolutionContactSource::createItem(const string &luid) { - logItem( uid, "extracting from EV", true ); + logItem(luid, "extracting from EV", true); EContact *contact; GError *gerror = NULL; - if (! e_book_get_contact( m_addressbook, - uid.c_str(), - &contact, - &gerror ) ) { - throwError( string( "reading contact " ) + uid, - gerror ); - } - eptr<EContact, GObject> contactptr( contact, "contact" ); - eptr<char> vcardstr(e_vcard_to_string( &contactptr->parent, - EVC_FORMAT_VCARD_30 ) ); + if (!e_book_get_contact(m_addressbook, + luid.c_str(), + &contact, + &gerror)) { + throwError(string("reading contact ") + luid, + gerror); + } + eptr<EContact, GObject> contactptr(contact, "contact"); + eptr<char> vcardstr(e_vcard_to_string(&contactptr->parent, + EVC_FORMAT_VCARD_30)); if (!vcardstr) { - throwError(string("failure extracting contact from Evolution " ) + uid); + throwError(string("failure extracting contact from Evolution " ) + luid); } SE_LOG_DEBUG(this, NULL, "%s", vcardstr.get()); +#if 0 + // @TODO reimplement Evolution hacks via Synthesis datatype conversions std::auto_ptr<VObject> vobj(VConverter::parse(vcardstr)); if (vobj.get() == 0) { throwError(string("failure parsing contact " ) + uid); @@ -477,17 +477,20 @@ SyncItem *EvolutionContactSource::createItem(const string &uid) arrayptr<char> finalstr(vobj->toString(), "VOCL string"); SE_LOG_DEBUG(this, NULL, "after conversion:"); SE_LOG_DEBUG(this, NULL, "%s", (char *)finalstr); +#endif - auto_ptr<SyncItem> item( new SyncItem( uid.c_str() ) ); - item->setData( (char *)finalstr, strlen(finalstr) ); - item->setDataType( getMimeType() ); - item->setModificationTime( 0 ); - + cxxptr<SyncItem> item(new SyncItem(), "SyncItem"); + item->setKey(luid); + item->setData(vcardstr.get(), strlen(vcardstr.get())); return item.release(); } string EvolutionContactSource::preparseVCard(SyncItem& item) { + return item.getData(); + +#if 0 + // @TODO Synthesis data conversion string data = (const char *)item.getData(); // convert to 3.0 to get rid of quoted-printable encoded // non-ASCII chars, because Evolution does not support @@ -672,52 +675,13 @@ string EvolutionContactSource::preparseVCard(SyncItem& item) SE_LOG_DEBUG(this, NULL, "after conversion to 3.0:"); SE_LOG_DEBUG(this, NULL, "%s", data.c_str()); return data; +#endif } -void EvolutionContactSource::setItemStatusThrow(const char *key, int status) -{ - switch (status) { - case STC_CONFLICT_RESOLVED_WITH_SERVER_DATA: { - // make a copy before allowing the server to overwrite it - - SE_LOG_ERROR(this, NULL, "contact %s: conflict, will be replaced by server contact - create copy", key); - - EContact *contact; - GError *gerror = NULL; - if (! e_book_get_contact( m_addressbook, - key, - &contact, - &gerror ) ) { - SE_LOG_ERROR(this, NULL, "item %.80s: reading original for copy failed", key); - break; - } - eptr<EContact, GObject> contactptr( contact, "contact" ); - EContact *copy = e_contact_duplicate(contact); - eptr<EContact, GObject> contactcopyptr(copy); - if(!copy || - ! e_book_add_contact(m_addressbook, - copy, - &gerror)) { - SE_LOG_ERROR(this, NULL, "item %.80s: making copy failed", key); - break; - } - break; - } - default: - EvolutionSyncSource::setItemStatusThrow(key, status); - break; - } -} - -int EvolutionContactSource::addItemThrow(SyncItem& item) +SyncMLStatus EvolutionContactSource::addItemThrow(SyncItem& item) { - int status = STC_OK; - string data; - if( strcmp(item.getDataType(), "raw" ) ) { - data = preparseVCard(item); - } else { - data = (const char *)item.getData(); - } + SyncMLStatus status = STATUS_OK; + string data = item.getData(); eptr<EContact, GObject> contact(e_contact_new_from_vcard(data.c_str())); if( contact ) { GError *gerror = NULL; @@ -733,9 +697,9 @@ int EvolutionContactSource::addItemThrow(SyncItem& item) return status; } -int EvolutionContactSource::updateItemThrow(SyncItem& item) +SyncMLStatus EvolutionContactSource::updateItemThrow(SyncItem& item) { - int status = STC_OK; + SyncMLStatus status = STATUS_OK; string data = preparseVCard(item); eptr<EContact, GObject> contact(e_contact_new_from_vcard(data.c_str())); if( contact ) { @@ -750,7 +714,7 @@ int EvolutionContactSource::updateItemThrow(SyncItem& item) // and committing once more, but that did not solve the problem. // // TODO: test with current Evolution - e_contact_set( contact, E_CONTACT_UID, (void *)item.getKey() ); + e_contact_set(contact, E_CONTACT_UID, (void *)item.getKey().c_str()); if ( e_book_commit_contact(m_addressbook, contact, &gerror) ) { const char *uid = (const char *)e_contact_get_const(contact, E_CONTACT_UID); if (uid) { @@ -783,15 +747,15 @@ int EvolutionContactSource::updateItemThrow(SyncItem& item) return status; } -int EvolutionContactSource::deleteItemThrow(SyncItem& item) +SyncMLStatus EvolutionContactSource::deleteItemThrow(SyncItem& item) { - int status = STC_OK; + SyncMLStatus status = STATUS_OK; GError *gerror = NULL; - if (!e_book_remove_contact( m_addressbook, item.getKey(), &gerror ) ) { + if (!e_book_remove_contact(m_addressbook, item.getKey().c_str(), &gerror)) { if (gerror->domain == E_BOOK_ERROR && gerror->code == E_BOOK_ERROR_CONTACT_NOT_FOUND) { SE_LOG_DEBUG(this, NULL, "%s: %s: request to delete non-existant contact ignored", - getName(), item.getKey()); + getName(), item.getKey().c_str()); g_clear_error(&gerror); } else { throwError( string( "deleting contact " ) + item.getKey(), @@ -886,9 +850,7 @@ void EvolutionContactSource::logItem(const SyncItem &item, const string &info, b line += "<unnamed contact>"; } - if (!item.getKey() ) { - line += ", NULL UID (?!)"; - } else if (!strlen( item.getKey() )) { + if (item.getKey().empty()) { line += ", empty UID"; } else { line += ", "; @@ -896,10 +858,10 @@ void EvolutionContactSource::logItem(const SyncItem &item, const string &info, b EContact *contact; GError *gerror = NULL; - if (e_book_get_contact( m_addressbook, - item.getKey(), - &contact, - &gerror )) { + if (e_book_get_contact(m_addressbook, + item.getKey().c_str(), + &contact, + &gerror)) { eptr<EContact, GObject> contactptr( contact, "contact" ); line += ", EV "; diff --git a/src/backends/evolution/EvolutionContactSource.h b/src/backends/evolution/EvolutionContactSource.h index 3df746db..17ac6fd6 100644 --- a/src/backends/evolution/EvolutionContactSource.h +++ b/src/backends/evolution/EvolutionContactSource.h @@ -49,10 +49,9 @@ class EvolutionContactSource : public EvolutionSyncSource bool needPartial, bool deleteLocal); virtual void endSyncThrow(); - virtual void setItemStatusThrow(const char *key, int status); - virtual int addItemThrow(SyncItem& item); - virtual int updateItemThrow(SyncItem& item); - virtual int deleteItemThrow(SyncItem& item); + virtual SyncMLStatus addItemThrow(SyncItem& item); + virtual SyncMLStatus updateItemThrow(SyncItem& item); + virtual SyncMLStatus deleteItemThrow(SyncItem& item); virtual void logItem(const string &uid, const string &info, bool debug = false); virtual void logItem(const SyncItem &item, const string &info, bool debug = false); diff --git a/src/backends/evolution/EvolutionMemoSource.cpp b/src/backends/evolution/EvolutionMemoSource.cpp index 74601bfd..28b8396a 100644 --- a/src/backends/evolution/EvolutionMemoSource.cpp +++ b/src/backends/evolution/EvolutionMemoSource.cpp @@ -20,9 +20,8 @@ SyncItem *EvolutionMemoSource::createItem(const string &luid) ItemID id(luid); eptr<icalcomponent> comp(retrieveItem(id)); - auto_ptr<SyncItem> item(new SyncItem(luid.c_str())); - - item->setData("", 0); + cxxptr<SyncItem> item(new SyncItem(), "SyncItem"); + item->setKey(luid); icalcomponent *cal = icalcomponent_get_first_component(comp, ICAL_VCALENDAR_COMPONENT); if (!cal) { cal = comp; @@ -90,23 +89,20 @@ SyncItem *EvolutionMemoSource::createItem(const string &luid) item->setData(dostext, strlen(dostext)); } } - item->setDataType("text/plain"); - item->setModificationTime(0); return item.release(); } EvolutionCalendarSource::InsertItemResult EvolutionMemoSource::insertItem(const string &luid, const SyncItem &item) { - const char *type = item.getDataType(); + string type = item.getDataType(); // fall back to inserting iCalendar 2.0 if // real SyncML server has sent vCalendar 1.0 or iCalendar 2.0 // or the test system inserts such an item - if (!type[0] || - !strcasecmp(type, "raw") || - !strcasecmp(type, "text/x-vcalendar") || - !strcasecmp(type, "text/calendar")) { + if (!strcasecmp(type.c_str(), "raw") || + !strcasecmp(type.c_str(), "text/x-vcalendar") || + !strcasecmp(type.c_str(), "text/calendar")) { return EvolutionCalendarSource::insertItem(luid, item); } diff --git a/src/backends/file/FileSyncSource.cpp b/src/backends/file/FileSyncSource.cpp index fb9612c1..86606133 100644 --- a/src/backends/file/FileSyncSource.cpp +++ b/src/backends/file/FileSyncSource.cpp @@ -151,12 +151,9 @@ SyncItem *FileSyncSource::createItem(const string &uid) } string content = out.str(); - auto_ptr<SyncItem> item(new SyncItem(uid.c_str())); + cxxptr<SyncItem> item(new SyncItem(), "SyncItem"); + item->setKey(uid); item->setData(content.c_str(), content.size()); - item->setDataType(getMimeType()); - // probably not even used by Funambol client library... - item->setModificationTime(0); - return item.release(); } diff --git a/src/backends/sqlite/Makefile.am b/src/backends/sqlite/Makefile.am index 70975b2c..9a699cbc 100644 --- a/src/backends/sqlite/Makefile.am +++ b/src/backends/sqlite/Makefile.am @@ -29,7 +29,7 @@ syncsqlite_la_CXXFLAGS = $(SYNCEVOLUTION_CXXFLAGS) # SQLiteContactSource does not support all fields from Funambol vCard 2.1 # test cases: filter them out before testing -../../testcases/sqlite_vcard21.vcf: $(FUNAMBOL_SUBDIR)/test/test/testcases/vcard21.vcf - mkdir -p ${@D} - perl -e '$$_ = join("", <>); s/^(ADR|TEL|EMAIL|PHOTO).*?(?=^\S)//msg; s/;X-EVOLUTION-UI-SLOT=\d+//g; print;' $< >$@ -all: ../../testcases/sqlite_vcard21.vcf +#../../testcases/sqlite_vcard21.vcf: $(FUNAMBOL_SUBDIR)/test/test/testcases/vcard21.vcf +# mkdir -p ${@D} +# perl -e '$$_ = join("", <>); s/^(ADR|TEL|EMAIL|PHOTO).*?(?=^\S)//msg; s/;X-EVOLUTION-UI-SLOT=\d+//g; print;' $< >$@ +# all: ../../testcases/sqlite_vcard21.vcf diff --git a/src/core/EvolutionSyncClient.cpp b/src/core/EvolutionSyncClient.cpp index a6ca49c7..610c2c61 100644 --- a/src/core/EvolutionSyncClient.cpp +++ b/src/core/EvolutionSyncClient.cpp @@ -49,8 +49,13 @@ EvolutionSyncClient::EvolutionSyncClient(const string &server, m_quiet(false), m_engine(new sysync::TEngineModuleBridge()) { - // Use libsynthesis that we were linked against. The name - // of a .so could be given here, too, to use that instead. + // Use libsynthesis that we were linked against. The name of a + // .so could be given here, too, to use that instead. This + // instance of the engine is used outside of the sync session + // itself. doSync() then creates another engine for the sync + // itself. That is necessary because the engine shutdown depends + // on the context of the sync (in particular instantiated sync + // sources). sysync::TSyError err = m_engine->Connect("[]", 0, sysync::DBG_PLUGIN_NONE| sysync::DBG_PLUGIN_INT| @@ -312,9 +317,7 @@ class SourceList : public vector<EvolutionSyncSource *> { LogDir m_logdir; /**< our logging directory */ bool m_prepared; /**< remember whether syncPrepare() dumped databases successfully */ bool m_doLogging; /**< true iff additional files are to be written during sync */ - SyncClient &m_client; /**< client which holds the sync report after a sync */ bool m_reportTodo; /**< true if syncDone() shall print a final report */ - boost::scoped_array<SyncSource *> m_sourceArray; /** owns the array that is expected by SyncClient::sync() */ const bool m_quiet; /**< avoid redundant printing to screen */ string m_previousLogdir; /**< remember previous log dir before creating the new one */ @@ -361,11 +364,10 @@ public: } } - SourceList(const string &server, bool doLogging, SyncClient &client, bool quiet) : + SourceList(const string &server, bool doLogging, bool quiet) : m_logdir(server), m_prepared(false), m_doLogging(doLogging), - m_client(client), m_reportTodo(true), m_quiet(quiet) { @@ -502,8 +504,8 @@ public: for (EvolutionSyncSource::ItemLocation location = EvolutionSyncSource::ITEM_LOCAL; location <= EvolutionSyncSource::ITEM_REMOTE; location = EvolutionSyncSource::ItemLocation(int(location) + 1)) { - for (EvolutionSyncSource::ItemState state = EvolutionSyncSource::ITEM_STATE_ADDED; - state <= EvolutionSyncSource::ITEM_STATE_REMOVED; + for (EvolutionSyncSource::ItemState state = EvolutionSyncSource::ITEM_ADDED; + state <= EvolutionSyncSource::ITEM_REMOVED; state = EvolutionSyncSource::ItemState(int(state) + 1)) { cout << right << setw(number_width) << source->getItemStat(location, state, EvolutionSyncSource::ITEM_REJECT); @@ -515,24 +517,24 @@ public: } int total_conflicts = source->getItemStat(EvolutionSyncSource::ITEM_REMOTE, - EvolutionSyncSource::ITEM_STATE_ANY, + EvolutionSyncSource::ITEM_ANY, EvolutionSyncSource::ITEM_CONFLICT_SERVER_WON) + source->getItemStat(EvolutionSyncSource::ITEM_REMOTE, - EvolutionSyncSource::ITEM_STATE_ANY, + EvolutionSyncSource::ITEM_ANY, EvolutionSyncSource::ITEM_CONFLICT_CLIENT_WON) + source->getItemStat(EvolutionSyncSource::ITEM_REMOTE, - EvolutionSyncSource::ITEM_STATE_ANY, + EvolutionSyncSource::ITEM_ANY, EvolutionSyncSource::ITEM_CONFLICT_DUPLICATED); cout << right << setw(number_width + 1) << total_conflicts; cout << " |\n"; stringstream sent, received; sent << source->getItemStat(EvolutionSyncSource::ITEM_LOCAL, - EvolutionSyncSource::ITEM_STATE_ANY, + EvolutionSyncSource::ITEM_ANY, EvolutionSyncSource::ITEM_SENT_BYTES) / 1024 << " KB sent by client"; received << source->getItemStat(EvolutionSyncSource::ITEM_LOCAL, - EvolutionSyncSource::ITEM_STATE_ANY, + EvolutionSyncSource::ITEM_ANY, EvolutionSyncSource::ITEM_RECEIVED_BYTES) / 1024 << " KB received"; cout << "|" << left << setw(name_width) << "" << " |" << @@ -547,7 +549,7 @@ public: result = EvolutionSyncSource::ItemResult(int(result) + 1)) { int count; if ((count = source->getItemStat(EvolutionSyncSource::ITEM_REMOTE, - EvolutionSyncSource::ITEM_STATE_ANY, + EvolutionSyncSource::ITEM_ANY, result)) != 0 || true) { stringstream line; line << count << " " << @@ -562,7 +564,7 @@ public: } int total_matched = source->getItemStat(EvolutionSyncSource::ITEM_REMOTE, - EvolutionSyncSource::ITEM_STATE_ANY, + EvolutionSyncSource::ITEM_ANY, EvolutionSyncSource::ITEM_MATCH); if (total_matched) { cout << "|" << left << setw(name_width) << "" << "| " << left << @@ -599,19 +601,6 @@ public: } } - /** returns current sources as array as expected by SyncClient::sync(), memory owned by this class */ - SyncSource **getSourceArray() { - m_sourceArray.reset(new SyncSource *[size() + 1]); - - int index = 0; - BOOST_FOREACH(EvolutionSyncSource *source, *this) { - m_sourceArray[index] = source; - index++; - } - m_sourceArray[index] = 0; - return &m_sourceArray[0]; - } - /** returns names of active sources */ set<string> getSources() { set<string> res; @@ -783,15 +772,15 @@ void EvolutionSyncClient::displaySourceProgress(sysync::TEngineProgressEventType extra2=# updated, extra3=# deleted) */ source.setItemStat(EvolutionSyncSource::ITEM_LOCAL, - EvolutionSyncSource::ITEM_STATE_ADDED, + EvolutionSyncSource::ITEM_ADDED, EvolutionSyncSource::ITEM_TOTAL, extra1); source.setItemStat(EvolutionSyncSource::ITEM_LOCAL, - EvolutionSyncSource::ITEM_STATE_UPDATED, + EvolutionSyncSource::ITEM_UPDATED, EvolutionSyncSource::ITEM_TOTAL, extra2); source.setItemStat(EvolutionSyncSource::ITEM_LOCAL, - EvolutionSyncSource::ITEM_STATE_REMOVED, + EvolutionSyncSource::ITEM_REMOVED, EvolutionSyncSource::ITEM_TOTAL, extra3); break; @@ -800,15 +789,15 @@ void EvolutionSyncClient::displaySourceProgress(sysync::TEngineProgressEventType extra2=# updated, extra3=# deleted) */ source.setItemStat(EvolutionSyncSource::ITEM_REMOTE, - EvolutionSyncSource::ITEM_STATE_ADDED, + EvolutionSyncSource::ITEM_ADDED, EvolutionSyncSource::ITEM_TOTAL, extra1); source.setItemStat(EvolutionSyncSource::ITEM_REMOTE, - EvolutionSyncSource::ITEM_STATE_UPDATED, + EvolutionSyncSource::ITEM_UPDATED, EvolutionSyncSource::ITEM_TOTAL, extra2); source.setItemStat(EvolutionSyncSource::ITEM_REMOTE, - EvolutionSyncSource::ITEM_STATE_REMOVED, + EvolutionSyncSource::ITEM_REMOVED, EvolutionSyncSource::ITEM_TOTAL, extra3); break; @@ -816,18 +805,18 @@ void EvolutionSyncClient::displaySourceProgress(sysync::TEngineProgressEventType /* datastore statistics for local/remote rejects (extra1=# locally rejected, extra2=# remotely rejected) */ source.setItemStat(EvolutionSyncSource::ITEM_LOCAL, - EvolutionSyncSource::ITEM_STATE_ANY, + EvolutionSyncSource::ITEM_ANY, EvolutionSyncSource::ITEM_REJECT, extra1); source.setItemStat(EvolutionSyncSource::ITEM_REMOTE, - EvolutionSyncSource::ITEM_STATE_ANY, + EvolutionSyncSource::ITEM_ANY, EvolutionSyncSource::ITEM_REJECT, extra2); break; case PEV_DSSTATS_S: /* datastore statistics for server slowsync (extra1=# slowsync matches) */ source.setItemStat(EvolutionSyncSource::ITEM_REMOTE, - EvolutionSyncSource::ITEM_STATE_ANY, + EvolutionSyncSource::ITEM_ANY, EvolutionSyncSource::ITEM_MATCH, extra1); break; @@ -836,15 +825,15 @@ void EvolutionSyncClient::displaySourceProgress(sysync::TEngineProgressEventType extra2=# client won, extra3=# duplicated) */ source.setItemStat(EvolutionSyncSource::ITEM_REMOTE, - EvolutionSyncSource::ITEM_STATE_ANY, + EvolutionSyncSource::ITEM_ANY, EvolutionSyncSource::ITEM_CONFLICT_SERVER_WON, extra1); source.setItemStat(EvolutionSyncSource::ITEM_REMOTE, - EvolutionSyncSource::ITEM_STATE_ANY, + EvolutionSyncSource::ITEM_ANY, EvolutionSyncSource::ITEM_CONFLICT_CLIENT_WON, extra2); source.setItemStat(EvolutionSyncSource::ITEM_REMOTE, - EvolutionSyncSource::ITEM_STATE_ANY, + EvolutionSyncSource::ITEM_ANY, EvolutionSyncSource::ITEM_CONFLICT_DUPLICATED, extra3); break; @@ -852,11 +841,11 @@ void EvolutionSyncClient::displaySourceProgress(sysync::TEngineProgressEventType /* datastore statistics for data volume (extra1=outgoing bytes, extra2=incoming bytes) */ source.setItemStat(EvolutionSyncSource::ITEM_LOCAL, - EvolutionSyncSource::ITEM_STATE_ANY, + EvolutionSyncSource::ITEM_ANY, EvolutionSyncSource::ITEM_SENT_BYTES, extra1); source.setItemStat(EvolutionSyncSource::ITEM_LOCAL, - EvolutionSyncSource::ITEM_STATE_ANY, + EvolutionSyncSource::ITEM_ANY, EvolutionSyncSource::ITEM_RECEIVED_BYTES, extra2); break; @@ -949,21 +938,6 @@ EvolutionSyncSource *EvolutionSyncClient::findSource(const char *name) return m_sourceListPtr ? (*m_sourceListPtr)[name] : NULL; } -AbstractSyncSourceConfig* EvolutionSyncClient::getAbstractSyncSourceConfig(const char* name) const -{ - return m_sourceListPtr ? (*m_sourceListPtr)[name] : NULL; -} - -AbstractSyncSourceConfig* EvolutionSyncClient::getAbstractSyncSourceConfig(unsigned int i) const -{ - return m_sourceListPtr ? (*m_sourceListPtr)[i] : NULL; -} - -unsigned int EvolutionSyncClient::getAbstractSyncSourceConfigsCount() const -{ - return m_sourceListPtr ? m_sourceListPtr->size() : 0; -} - void EvolutionSyncClient::setConfigFilter(bool sync, const FilterConfigNode::ConfigFilter &filter) { map<string, string>::const_iterator hasSync = filter.find(EvolutionSyncSourceConfig::m_sourcePropSync.getName()); @@ -1146,7 +1120,7 @@ int EvolutionSyncClient::sync() } // redirect logging as soon as possible - SourceList sourceList(m_server, m_doLogging, *this, m_quiet); + SourceList sourceList(m_server, m_doLogging, m_quiet); m_sourceListPtr = &sourceList; try { @@ -1189,29 +1163,13 @@ int EvolutionSyncClient::sync() } // give derived class also a chance to update the configs - prepare(sourceList.getSourceArray()); + prepare(sourceList); // ready to go: dump initial databases and prepare for final report sourceList.syncPrepare(); -#ifndef SYNTHESIS - // do it - res = SyncClient::sync(*this, sourceList.getSourceArray()); - - // store modified properties: must be done even after failed - // sync because the source's anchor might have been reset - flush(); - - if (res) { - if (getLastErrorCode() && getLastErrorMsg() && getLastErrorMsg()[0]) { - throwError(getLastErrorMsg()); - } - // no error code/description?! - throwError("sync failed without an error description, check log"); - } -#else + // run sync session doSync(); -#endif // all went well: print final report before cleaning up sourceList.syncDone(true); @@ -1233,13 +1191,11 @@ int EvolutionSyncClient::sync() return res; } -void EvolutionSyncClient::prepare(SyncSource **sources) { +void EvolutionSyncClient::prepare(const std::vector<EvolutionSyncSource *> &sources) { if (m_syncMode != SYNC_NONE) { - for (SyncSource **source = sources; - *source; - source++) { - (*source)->setPreferredSyncMode(m_syncMode); - } + // BOOST_FOREACH(EvolutionSyncSource *source, sources) { + // @TODO source->setPreferredSyncMode(m_syncMode); + // } } } @@ -1251,6 +1207,35 @@ void EvolutionSyncClient::doSync() sysync::KeyH subkeyH; string s; + // create new sync engine for the duration of this function + class SwapEngine { + EvolutionSyncClient &m_client; + sysync::TEngineModuleBridge *m_oldengine; + + public: + SwapEngine(EvolutionSyncClient &client) : + m_client(client) { + sysync::TEngineModuleBridge *syncengine = new sysync::TEngineModuleBridge(); + sysync::TSyError err; + if (!syncengine || + (err = syncengine->Connect("[]", 0, + sysync::DBG_PLUGIN_NONE| + sysync::DBG_PLUGIN_INT| + sysync::DBG_PLUGIN_DB| + sysync::DBG_PLUGIN_EXOT| + sysync::DBG_PLUGIN_ALL))) { + m_client.throwError("create Syntesis engine for sync session"); + } + m_oldengine = m_client.swapEngine(syncengine); + } + + ~SwapEngine() { + sysync::TEngineModuleBridge *syncengine = + m_client.swapEngine(m_oldengine); + delete syncengine; + } + } swapengine(*this); + err = getEngine().OpenKeyByPath(keyH, NULL, "/configvars", 0); if (err) { throwError("open config vars"); @@ -1551,7 +1536,7 @@ void EvolutionSyncClient::status() throwError("cannot proceed without configuration"); } - SourceList sourceList(m_server, false, *this, false); + SourceList sourceList(m_server, false, false); initSources(sourceList); BOOST_FOREACH(EvolutionSyncSource *source, sourceList) { source->checkPassword(*this); @@ -1560,7 +1545,7 @@ void EvolutionSyncClient::status() source->open(); } - sourceList.setLogdir(getLogDir(), 0, LOG_LEVEL_NONE); + sourceList.setLogdir(getLogDir(), 0, 0); LoggerBase::instance().setLevel(Logger::INFO); string prevLogdir = sourceList.getPrevLogdir(); bool found = access(prevLogdir.c_str(), R_OK|X_OK) == 0; diff --git a/src/core/EvolutionSyncClient.h b/src/core/EvolutionSyncClient.h index 7f134fb0..b4b65947 100644 --- a/src/core/EvolutionSyncClient.h +++ b/src/core/EvolutionSyncClient.h @@ -9,8 +9,7 @@ #include "EvolutionSmartPtr.h" #include "SyncEvolutionConfig.h" -#include <client/SyncClient.h> -#include <spds/SyncManagerConfig.h> +#include "SyncML.h" #include <string> #include <set> @@ -42,7 +41,7 @@ namespace sysync { * implementation of those uses stdin/out. * */ -class EvolutionSyncClient : public SyncClient, public EvolutionSyncConfig, public ConfigUserInterface { +class EvolutionSyncClient : public EvolutionSyncConfig, public ConfigUserInterface { const string m_server; const set<string> m_sources; const bool m_doLogging; @@ -146,11 +145,6 @@ class EvolutionSyncClient : public SyncClient, public EvolutionSyncConfig, publi */ static EvolutionSyncSource *findSource(const char *name); - /* AbstractSyncConfig API */ - virtual AbstractSyncSourceConfig* getAbstractSyncSourceConfig(const char* name) const; - virtual AbstractSyncSourceConfig* getAbstractSyncSourceConfig(unsigned int i) const; - virtual unsigned int getAbstractSyncSourceConfigsCount() const; - /** * intercept config filters * @@ -166,6 +160,12 @@ class EvolutionSyncClient : public SyncClient, public EvolutionSyncConfig, publi sysync::TEngineModuleBridge &getEngine() { return *m_engine; } const sysync::TEngineModuleBridge &getEngine() const { return *m_engine; } + sysync::TEngineModuleBridge *swapEngine(sysync::TEngineModuleBridge *newengine) { + sysync::TEngineModuleBridge *oldengine = m_engine; + m_engine = newengine; + return oldengine; + } + /** * Return skeleton Synthesis client XML configuration. * @@ -216,7 +216,7 @@ class EvolutionSyncClient : public SyncClient, public EvolutionSyncConfig, publi * * @param sources a NULL terminated array of all active sources */ - virtual void prepare(SyncSource **sources); + virtual void prepare(const std::vector<EvolutionSyncSource *> &sources); /** * instantiate transport agent diff --git a/src/core/EvolutionSyncSource.cpp b/src/core/EvolutionSyncSource.cpp index 7b0bd770..5d5e0bcc 100644 --- a/src/core/EvolutionSyncSource.cpp +++ b/src/core/EvolutionSyncSource.cpp @@ -77,9 +77,7 @@ void EvolutionSyncSource::handleException() try { throw; } catch (std::exception &ex) { - setErrorF(getLastErrorCode() == ERR_NONE ? ERR_UNSPECIFIED : getLastErrorCode(), - "%s", ex.what()); - SE_LOG_ERROR(this, NULL, "%s", getLastErrorMsg()); + SE_LOG_ERROR(this, NULL, "%s", ex.what()); setFailed(true); } } @@ -342,20 +340,19 @@ void EvolutionSyncSource::getDatastoreXML(string &xml) xml = xmlstream.str(); } -int EvolutionSyncSource::beginSync() throw() +SyncMLStatus EvolutionSyncSource::beginSync(SyncMode mode) throw() { - SyncMode mode = getSyncMode(); - // start background thread if not running yet: // necessary to catch problems with Evolution backend EvolutionSyncClient::startLoopThread(); try { + // @TODO: force slow sync if something goes wrong + // // reset anchors now, once we proceed there is no going back // (because the change marker is about to be moved) // and the sync must either complete or result in a slow sync // the next time - getConfig().setLast(0); const char *error = getenv("SYNCEVOLUTION_BEGIN_SYNC_ERROR"); if (error && strstr(error, getName())) { @@ -409,9 +406,9 @@ int EvolutionSyncSource::beginSync() throw() rewindItems(); } catch( ... ) { handleException(); - return 1; + return STATUS_FATAL; } - return 0; + return STATUS_OK; } void EvolutionSyncSource::rewindItems() throw() @@ -419,19 +416,19 @@ void EvolutionSyncSource::rewindItems() throw() m_allItems.rewind(); } -EvolutionSyncSource::NextItemState EvolutionSyncSource::nextItem(string *data, string &luid) throw() +SyncItem::State EvolutionSyncSource::nextItem(string *data, string &luid) throw() { /** @TODO: avoid reading data if not necessary */ SyncItem *item = m_allItems.iterate(); - NextItemState state = ITEM_EOF; + SyncItem::State state = SyncItem::NO_MORE_ITEMS; if (item) { if (m_newItems.find(item->getKey()) != m_newItems.end()) { - state = ITEM_NEW; + state = SyncItem::NEW; } else if (m_updatedItems.find(item->getKey()) != m_updatedItems.end()) { - state = ITEM_UPDATED; + state = SyncItem::UPDATED; } else { - state = ITEM_UNCHANGED; + state = SyncItem::UNCHANGED; } if (data) { data->assign((const char *)item->getData(), item->getDataSize()); @@ -441,7 +438,7 @@ EvolutionSyncSource::NextItemState EvolutionSyncSource::nextItem(string *data, s return state; } -int EvolutionSyncSource::endSync() throw() +SyncMLStatus EvolutionSyncSource::endSync() throw() { try { endSyncThrow(); @@ -449,41 +446,31 @@ int EvolutionSyncSource::endSync() throw() handleException(); } - // Do _not_ tell the caller (SyncManager) if an error occurred + // @TODO: Do _not_ tell the caller (SyncManager) if an error occurred // because that causes Sync4jClient to abort processing for all // sync sources. Instead deal with failed sync sources in // EvolutionSyncClient::sync(). - return 0; -} - -void EvolutionSyncSource::setItemStatus(const char *key, int status) throw() -{ - try { - // TODO: logging - setItemStatusThrow(key, status); - } catch (...) { - handleException(); - } + return STATUS_OK; } -int EvolutionSyncSource::addItem(SyncItem& item) throw() +SyncMLStatus EvolutionSyncSource::addItem(SyncItem& item) throw() { return processItem("add", &EvolutionSyncSource::addItemThrow, item, true); } -int EvolutionSyncSource::updateItem(SyncItem& item) throw() +SyncMLStatus EvolutionSyncSource::updateItem(SyncItem& item) throw() { return processItem("update", &EvolutionSyncSource::updateItemThrow, item, true); } -int EvolutionSyncSource::deleteItem(SyncItem& item) throw() +SyncMLStatus EvolutionSyncSource::deleteItem(SyncItem& item) throw() { return processItem("delete", &EvolutionSyncSource::deleteItemThrow, item, false); } -int EvolutionSyncSource::removeAllItems() throw() +SyncMLStatus EvolutionSyncSource::removeAllItems() throw() { - int status = 0; + SyncMLStatus status = STATUS_OK; try { BOOST_FOREACH(const string &key, m_allItems) { @@ -495,17 +482,17 @@ int EvolutionSyncSource::removeAllItems() throw() } } catch (...) { handleException(); - status = 1; + status = STATUS_FATAL; } return status; } -int EvolutionSyncSource::processItem(const char *action, - int (EvolutionSyncSource::*func)(SyncItem& item), - SyncItem& item, - bool needData) throw() +SyncMLStatus EvolutionSyncSource::processItem(const char *action, + SyncMLStatus (EvolutionSyncSource::*func)(SyncItem& item), + SyncItem& item, + bool needData) throw() { - int status = STC_COMMAND_FAILED; + SyncMLStatus status = STATUS_FATAL; try { logItem(item, action); @@ -514,7 +501,7 @@ int EvolutionSyncSource::processItem(const char *action, // Shouldn't happen, but it did with one server and thus this // security check was added to prevent segfaults. logItem(item, "ignored due to missing data"); - status = STC_OK; + status = STATUS_OK; } else { status = (this->*func)(item); } @@ -526,21 +513,6 @@ int EvolutionSyncSource::processItem(const char *action, return status; } -void EvolutionSyncSource::setItemStatusThrow(const char *key, int status) -{ - switch (status) { - case STC_ALREADY_EXISTS: - // found pair during slow sync, that's okay - break; - default: - if (status < 200 || status > 300) { - SE_LOG_ERROR(this, NULL, "unexpected SyncML status response %d for item %.80s\n", - status, key); - setFailed(true); - } - } -} - void EvolutionSyncSource::sleepSinceModification(int seconds) { time_t current = time(NULL); @@ -670,16 +642,13 @@ SyncItem *EvolutionSyncSource::Items::iterate() if (&m_source.m_deletedItems == this) { // just tell caller the uid of the deleted item // and the type that it probably had - SyncItem *item = new SyncItem( uid.c_str() ); - item->setDataType(m_source.getMimeType()); - return item; + cxxptr<SyncItem> item(new SyncItem()); + item->setKey(uid); + return item.release(); } else { // retrieve item with all its data try { cxxptr<SyncItem> item(m_source.createItem(uid)); - if (item) { - item->setState(m_state); - } return item.release(); } catch(...) { m_source.handleException(); diff --git a/src/core/EvolutionSyncSource.h b/src/core/EvolutionSyncSource.h index 69c3cd3f..6e909b78 100644 --- a/src/core/EvolutionSyncSource.h +++ b/src/core/EvolutionSyncSource.h @@ -9,6 +9,8 @@ #include "SyncEvolutionConfig.h" #include "EvolutionSmartPtr.h" #include "Logging.h" +#include "eds_abi_wrapper.h" +#include "SyncML.h" using namespace SyncEvolution; #include <boost/shared_ptr.hpp> @@ -21,11 +23,6 @@ using namespace std; #include <time.h> -#include <spds/SyncSource.h> -#include <spdm/ManagementNode.h> -#include "Logging.h" - -#include "eds_abi_wrapper.h" class EvolutionSyncSource; #include <synthesis/sync_declarations.h> @@ -242,7 +239,7 @@ class RegisterSyncSourceTest * sources which normally use one format internally, but also * support another one (EvolutionContactSource). */ - static int dump(ClientTest &client, SyncSource &source, const char *file); + static int dump(ClientTest &client, EvolutionSyncSource &source, const char *file); const string m_configName; const string m_testCaseName; @@ -263,7 +260,6 @@ class TestRegistry : public vector<const RegisterSyncSourceTest *> } }; - /** * SyncEvolution accesses all sources through this interface. This * class also implements common functionality for all SyncSources: @@ -284,25 +280,23 @@ class TestRegistry : public vector<const RegisterSyncSourceTest *> * * It also adds Evolution specific interfaces and utility functions. */ -class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig, public LoggerBase +class EvolutionSyncSource : public EvolutionSyncSourceConfig, public LoggerBase { public: /** * Creates a new Evolution sync source. */ EvolutionSyncSource(const EvolutionSyncSourceParams ¶ms) : - SyncSource(params.m_name.c_str(), NULL), EvolutionSyncSourceConfig(params.m_name, params.m_nodes), m_changeId( params.m_changeId ), - m_allItems( *this, "existing", SYNC_STATE_NONE ), - m_newItems( *this, "new", SYNC_STATE_NEW ), - m_updatedItems( *this, "updated", SYNC_STATE_UPDATED ), - m_deletedItems( *this, "deleted", SYNC_STATE_DELETED ), + m_allItems( *this, "existing", SyncItem::NONE ), + m_newItems( *this, "new", SyncItem::NEW ), + m_updatedItems( *this, "updated", SyncItem::UPDATED ), + m_deletedItems( *this, "deleted", SyncItem::DELETED ), m_isModified( false ), m_modTimeStamp(0), m_hasFailed( false ) { - setConfig(this); memset(m_stat, 0, sizeof(m_stat)); } virtual ~EvolutionSyncSource() {} @@ -412,8 +406,25 @@ class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig, * (between SyncEvolution_Module_CreateContext() and * SyncEvolution_Module_DeleteContext()) */ - sysync::SDK_InterfaceType *getSynthesisAPI() { return m_synthesisAPI; } - void setSynthesisAPI(sysync::SDK_InterfaceType *synthesisAPI) { m_synthesisAPI = synthesisAPI; } + sysync::SDK_InterfaceType *getSynthesisAPI() { + return m_synthesisAPI.empty() ? + NULL : + m_synthesisAPI[m_synthesisAPI.size() - 1]; + } + + /** + * change the Synthesis API that is used by the source + */ + void pushSynthesisAPI(sysync::SDK_InterfaceType *synthesisAPI) { + m_synthesisAPI.push_back(synthesisAPI); + } + + /** + * remove latest Synthesis API and return to previous one (if any) + */ + void popSynthesisAPI() { + m_synthesisAPI.pop_back(); + } /** * Convenience function, to be called inside a catch() block of @@ -519,13 +530,6 @@ class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig, virtual SyncItem* getNextItemKey() throw() { return m_allItems.iterate(); } /**@}*/ - enum NextItemState { - ITEM_UNCHANGED, /**< item is unchanged since last sync */ - ITEM_NEW, /**< new item */ - ITEM_UPDATED, /**< item was updated since last sync */ - ITEM_EOF, /**< no more items */ - ITEM_ERROR /**< item couldn't be extracted */ - }; /** * get information about next item * @@ -533,7 +537,7 @@ class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig, * @retval luid local ID of item * @return status of item or error */ - virtual NextItemState nextItem(string *data, string &luid) throw(); + virtual SyncItem::State nextItem(string *data, string &luid) throw(); /** * restart reading all items, automatically called at end of beginSync() @@ -545,12 +549,11 @@ class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig, * and implemented via the corresponding *Throw() calls */ /**@{*/ - virtual int beginSync() throw(); - virtual int endSync() throw(); - virtual void setItemStatus(const char *key, int status) throw(); - virtual int addItem(SyncItem& item) throw(); - virtual int updateItem(SyncItem& item) throw(); - virtual int deleteItem(SyncItem& item) throw(); + virtual SyncMLStatus beginSync(SyncMode mode) throw(); + virtual SyncMLStatus endSync() throw(); + virtual SyncMLStatus addItem(SyncItem& item) throw(); + virtual SyncMLStatus updateItem(SyncItem& item) throw(); + virtual SyncMLStatus deleteItem(SyncItem& item) throw(); /**@}*/ /** @@ -564,13 +567,7 @@ class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig, * * @return 0 for success, non-zero for failure */ - virtual int removeAllItems() throw(); - - /** - * Disambiguate getName(): we have inherited it from both SyncSource and - * AbstractSyncSourceConfig. Both must return the same string. - */ - const char *getName() throw() { return SyncSource::getName(); } + virtual SyncMLStatus removeAllItems() throw(); /** * source specific part of beginSync() - throws exceptions in case of error @@ -589,10 +586,9 @@ class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig, */ /**@{*/ virtual void endSyncThrow() = 0; - virtual void setItemStatusThrow(const char *key, int status); - virtual int addItemThrow(SyncItem& item) = 0; - virtual int updateItemThrow(SyncItem& item) = 0; - virtual int deleteItemThrow(SyncItem& item) = 0; + virtual SyncMLStatus addItemThrow(SyncItem& item) = 0; + virtual SyncMLStatus updateItemThrow(SyncItem& item) = 0; + virtual SyncMLStatus deleteItemThrow(SyncItem& item) = 0; /**@}*/ /** @@ -690,12 +686,10 @@ class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig, ITEM_LOCATION_MAX }; enum ItemState { - // TODO: remove _STATE_ once we got rid of Funambol header files; - // currently those have conflicting defines - ITEM_STATE_ADDED, - ITEM_STATE_UPDATED, - ITEM_STATE_REMOVED, - ITEM_STATE_ANY, + ITEM_ADDED, + ITEM_UPDATED, + ITEM_REMOVED, + ITEM_ANY, ITEM_STATE_MAX }; enum ItemResult { @@ -736,10 +730,10 @@ class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig, const_iterator m_it; EvolutionSyncSource &m_source; const string m_type; - const SyncState m_state; + const SyncItem::State m_state; public: - Items( EvolutionSyncSource &source, const string &type, SyncState state ) : + Items( EvolutionSyncSource &source, const string &type, SyncItem::State state ) : m_source( source ), m_type( type ), m_state( state ) @@ -790,10 +784,10 @@ class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig, /** * private wrapper function for add/delete/updateItemThrow() */ - int processItem(const char *action, - int (EvolutionSyncSource::*func)(SyncItem& item), - SyncItem& item, - bool needData) throw(); + SyncMLStatus processItem(const char *action, + SyncMLStatus (EvolutionSyncSource::*func)(SyncItem& item), + SyncItem& item, + bool needData) throw(); /** time stamp of latest database modification, for sleepSinceModification() */ time_t m_modTimeStamp; @@ -808,7 +802,7 @@ class EvolutionSyncSource : public SyncSource, public EvolutionSyncSourceConfig, * SyncEvolution_Module_DeleteContext(), in other words, while * the engine is running. */ - sysync::SDK_InterfaceType *m_synthesisAPI; + std::vector<sysync::SDK_InterfaceType *> m_synthesisAPI; /** storage for getItemStat() */ int m_stat[ITEM_LOCATION_MAX][ITEM_STATE_MAX][ITEM_RESULT_MAX]; diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 63b4456f..d1e85193 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -13,16 +13,6 @@ else noinst_LTLIBRARIES = libsyncevolution.la endif -VOCL_SOURCES = \ - vocl/VObject.h \ - vocl/VProperty.h \ - vocl/VConverter.h \ - vocl/posixadapter.h \ - \ - vocl/VObject.cpp \ - vocl/VProperty.cpp \ - vocl/VConverter.cpp - CORE_SOURCES = \ ConfigTree.h \ ConfigNode.h \ @@ -78,9 +68,8 @@ CORE_SOURCES = \ FileConfigTree.cpp \ \ TrackingSyncSource.h \ - TrackingSyncSource.cpp \ - \ - $(VOCL_SOURCES) + TrackingSyncSource.cpp + libsyncevolution_la_SOURCES = $(CORE_SOURCES) libsyncevolution_la_LIBADD = @EPACKAGE_LIBS@ @GLIB_LIBS@ @FUNAMBOL_LIBS@ $(TRANSPORT_LIBS) @LIBS@ $(SYNTHESIS_LIBS) diff --git a/src/core/SyncEvolutionConfig.h b/src/core/SyncEvolutionConfig.h index 96250c2c..cd117f8c 100644 --- a/src/core/SyncEvolutionConfig.h +++ b/src/core/SyncEvolutionConfig.h @@ -6,8 +6,6 @@ #include "FilterConfigNode.h" -#include "spds/AbstractSyncConfig.h" -#include "spds/AbstractSyncSourceConfig.h" #include <boost/shared_ptr.hpp> #include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/trim.hpp> @@ -446,7 +444,7 @@ class ConfigStringCache { * uses a FileConfigTree instance. Other implementations would be * possible. */ -class EvolutionSyncConfig : public AbstractSyncConfig { +class EvolutionSyncConfig { public: /** * Opens the configuration for a specific server, @@ -627,10 +625,6 @@ class EvolutionSyncConfig : public AbstractSyncConfig { */ /**@{*/ - virtual AbstractSyncSourceConfig* getAbstractSyncSourceConfig(const char* name) const { return NULL; } - virtual AbstractSyncSourceConfig* getAbstractSyncSourceConfig(unsigned int i) const { return NULL; } - virtual unsigned int getAbstractSyncSourceConfigsCount() const { return 0; } - virtual const char* getUsername() const; virtual void setUsername(const string &value, bool temporarily = false); virtual const char* getPassword() const; @@ -790,7 +784,7 @@ struct ConstSyncSourceNodes { * Some properties are not configurable and have to be provided * by derived classes. */ -class EvolutionSyncSourceConfig : public AbstractSyncSourceConfig { +class EvolutionSyncSourceConfig { public: EvolutionSyncSourceConfig(const string &name, const SyncSourceNodes &nodes); @@ -944,9 +938,9 @@ class EvolutionSyncSourceConfig : public AbstractSyncSourceConfig { * returning an empty array implies that it supports all aspects. * This is the default implementation of this call. * - * @return an ArrayList of CTCap + * @TODO: per-source capabilities */ - virtual const ArrayList& getCtCaps() const { static const ArrayList dummy; return dummy; } + // virtual const ArrayList& getCtCaps() const { static const ArrayList dummy; return dummy; } /**@}*/ diff --git a/src/core/SyncEvolutionUtil.cpp b/src/core/SyncEvolutionUtil.cpp index 58bb5ca0..b576bca9 100644 --- a/src/core/SyncEvolutionUtil.cpp +++ b/src/core/SyncEvolutionUtil.cpp @@ -2,10 +2,8 @@ * Copyright (C) 2008 Patrick Ohly */ -#include <config.h> #include "SyncEvolutionUtil.h" #include "EvolutionSyncClient.h" -#include <base/test.h> #include <boost/scoped_array.hpp> #include <boost/foreach.hpp> diff --git a/src/core/SyncEvolutionUtil.h b/src/core/SyncEvolutionUtil.h index 425d3862..523f8f88 100644 --- a/src/core/SyncEvolutionUtil.h +++ b/src/core/SyncEvolutionUtil.h @@ -5,8 +5,6 @@ #ifndef INCL_SYNCEVOLUTION_UTIL # define INCL_SYNCEVOLUTION_UTIL -#include <base/test.h> - #include <boost/algorithm/string/case_conv.hpp> #include <boost/algorithm/string/predicate.hpp> diff --git a/src/core/SyncML.h b/src/core/SyncML.h new file mode 100644 index 00000000..abe18f94 --- /dev/null +++ b/src/core/SyncML.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2009 Patrick Ohly + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * 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, TITLE, NONINFRINGEMENT 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., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + */ + +#ifndef INCL_SYNCML +#define INCL_SYNCML + +#include <string> + +enum SyncMode { + SYNC_NONE, + SYNC_TWO_WAY, + SYNC_SLOW, + SYNC_ONE_WAY_FROM_CLIENT, + SYNC_REFRESH_FROM_CLIENT, + SYNC_ONE_WAY_FROM_SERVER, + SYNC_REFRESH_FROM_SERVER, + SYNC_MODE_MAX +}; + +/** + * simple container for SyncML items + */ +class SyncItem { + private: + /** + * Data, might not be text. nul-byte not included in data size. + */ + std::string m_data; + /** + * Local unique ID of the item. + */ + std::string m_luid; + /** + * Empty string indicates the default format specified for a sync + * source. Might be set to a mime type (e.g. "text/calendar") to + * override the default format. + */ + std::string m_datatype; + + + public: + std::string getKey() const { return m_luid; } + void setKey(const std::string &key) { m_luid = key; } + const char *getData() const { return m_data.c_str(); } + size_t getDataSize() const { return m_data.size(); } + void setData(const char *data, size_t size) { m_data.assign(data, size); } + void setDataType(const std::string &datatype) { m_datatype = datatype; } + std::string getDataType() const { return m_datatype; } + + /** result of change tracking and iteration over items */ + enum State { + /** undefined state */ + NONE, + /** not changed */ + UNCHANGED, + /** item added */ + NEW, + /** item updated */ + UPDATED, + /** item deleted (only key, but no data available) */ + DELETED, + /** end of iteration */ + NO_MORE_ITEMS, + /** error reading item */ + ERROR, + + /** end of enumeration */ + STATE_MAX, + }; +}; + +/** + * result of SyncML operations, same codes as in HTTP and the Synthesis engine + */ +enum SyncMLStatus { + /** ok */ + STATUS_OK = 0, + + /** no content / end of file / end of iteration / empty/NULL value */ + STATUS_NO_CONTENT = 204, + /** external data has been merged */ + STATUS_DATA_MERGED = 207, + + /** forbidden / access denied */ + STATUS_FORBIDDEN = 403, + /** object not found / unassigned field */ + STATUS_NOT_FOUND = 404, + /** command not allowed */ + STATUS_COMMAND_NOT_ALLOWED = 405, + /** command failed / fatal DB error */ + STATUS_FATAL = 500, + /** general DB error */ + STATUS_DATASTORE_FAILURE = 510, + /** database / memory full error */ + STATUS_FULL = 420, + + STATUS_MAX = 0x7FFFFFF +}; + +#endif // INCL_SYNCML diff --git a/src/core/SynthesisDBPlugin.cpp b/src/core/SynthesisDBPlugin.cpp index b6ca0a29..3c318ab6 100644 --- a/src/core/SynthesisDBPlugin.cpp +++ b/src/core/SynthesisDBPlugin.cpp @@ -58,7 +58,7 @@ TSyError SyncEvolution_Module_CreateContext( CContext *mContext, cAppCharP mod TSyError err = LOCERR_WRONGUSAGE; EvolutionSyncSource *source = EvolutionSyncClient::findSource(mContextName); if (source) { - source->setSynthesisAPI(mCB); + source->pushSynthesisAPI(mCB); *mContext = (CContext)source; err = LOCERR_OK; } @@ -138,7 +138,7 @@ TSyError SyncEvolution_Module_DeleteContext( CContext mContext ) { EvolutionSyncSource *source = MoC(mContext); DEBUG_DB(source->getSynthesisAPI(), MyDB, Mo_DC, "'%s'", source->getName()); - source->setSynthesisAPI(NULL); + source->popSynthesisAPI(); return LOCERR_OK; } @@ -404,7 +404,7 @@ TSyError SyncEvolution_CreateContext( CContext *aContext, cAppCharP aContextName TSyError err = LOCERR_WRONGUSAGE; EvolutionSyncSource *source = EvolutionSyncClient::findSource(aContextName); if (source) { - source->setSynthesisAPI(aCB); + source->pushSynthesisAPI(aCB); *aContext = (CContext)source; err = LOCERR_OK; } @@ -587,12 +587,7 @@ TSyError SyncEvolution_StartDataRead( CContext aContext, cAppCharP lastToken, TSyError res; // tell EvolutionSyncSource to be prepared for anything - source->setSyncMode(SYNC_NONE); - if (source->beginSync()) { - res = DB_Fatal; - } else { - res = LOCERR_OK; - } + res = source->beginSync(SYNC_NONE); return res; } @@ -607,14 +602,14 @@ TSyError SyncEvolution_ReadNextItemAsKey( CContext aContext, ItemID aID, KeyH aI TSyError res = LOCERR_OK; string luid; switch (source->nextItem(NULL, luid)) { - case EvolutionSyncSource::ITEM_UNCHANGED: + case SyncItem::UNCHANGED: *aStatus = ReadNextItem_Unchanged; break; - case EvolutionSyncSource::ITEM_NEW: - case EvolutionSyncSource::ITEM_UPDATED: + case SyncItem::NEW: + case SyncItem::UPDATED: *aStatus = ReadNextItem_Changed; break; - case EvolutionSyncSource::ITEM_EOF: + case SyncItem::NO_MORE_ITEMS: *aStatus = ReadNextItem_EOF; break; default: @@ -731,15 +726,9 @@ TSyError SyncEvolution_InsertItemAsKey( CContext aContext, KeyH aItemKey, ItemID if (!res) { SyncItem item; item.setData(data, len); - switch (source->addItem(item)) { - case STC_CONFLICT_RESOLVED_WITH_MERGE: - case STC_OK: - newID->item = StrAlloc(item.getKey()); - newID->parent = StrAlloc(""); - break; - default: - res = DB_Fatal; - } + res = source->addItem(item); + newID->item = StrAlloc(item.getKey().c_str()); + newID->parent = StrAlloc(""); } delete [] data; @@ -778,16 +767,10 @@ TSyError SyncEvolution_UpdateItemAsKey( CContext aContext, KeyH aItemKey, cItemI SyncItem item; item.setData(data, len); item.setKey(aID->item); - switch (source->updateItem(item)) { - case STC_CONFLICT_RESOLVED_WITH_MERGE: - case STC_OK: - if (strcmp(item.getKey(), aID->item)) { - updID->item = StrAlloc(item.getKey()); - updID->parent = StrAlloc(""); - } - break; - default: - res = DB_Fatal; + res = source->updateItem(item); + if (item.getKey() == aID->item) { + updID->item = StrAlloc(item.getKey().c_str()); + updID->parent = StrAlloc(""); } } @@ -818,13 +801,7 @@ TSyError SyncEvolution_DeleteItem( CContext aContext, cItemID aID ) TSyError res = LOCERR_OK; SyncItem item; item.setKey(aID->item); - switch (source->deleteItem(item)) { - case STC_OK: - break; - default: - res = DB_Fatal; - break; - } + res = source->deleteItem(item); return res; } @@ -904,6 +881,6 @@ TSyError SyncEvolution_DeleteContext( CContext aContext ) /**** CAN BE ADAPTED BY USER ****/ EvolutionSyncSource *source = DBC( aContext ); DEBUG_DB( source->getSynthesisAPI(), MyDB,Da_DC, "%s", source->getName() ); - + source->popSynthesisAPI(); return LOCERR_OK; } diff --git a/src/core/TrackingSyncSource.cpp b/src/core/TrackingSyncSource.cpp index e4d7fdfc..c785ea44 100644 --- a/src/core/TrackingSyncSource.cpp +++ b/src/core/TrackingSyncSource.cpp @@ -126,7 +126,7 @@ void TrackingSyncSource::exportData(ostream &out) } } -int TrackingSyncSource::addItemThrow(SyncItem& item) +SyncMLStatus TrackingSyncSource::addItemThrow(SyncItem& item) { InsertItemResult res = insertItem("", item); item.setKey(res.m_uid.c_str()); @@ -134,10 +134,10 @@ int TrackingSyncSource::addItemThrow(SyncItem& item) throwError("could not add item"); } m_trackingNode->setProperty(res.m_uid, res.m_revision); - return res.m_merged ? STC_CONFLICT_RESOLVED_WITH_MERGE : STC_OK; + return res.m_merged ? STATUS_DATA_MERGED : STATUS_OK; } -int TrackingSyncSource::updateItemThrow(SyncItem& item) +SyncMLStatus TrackingSyncSource::updateItemThrow(SyncItem& item) { const string uid = item.getKey(); InsertItemResult res = insertItem(uid, item); @@ -149,17 +149,13 @@ int TrackingSyncSource::updateItemThrow(SyncItem& item) throwError("could not update item"); } m_trackingNode->setProperty(res.m_uid, res.m_revision); - return res.m_merged ? STC_CONFLICT_RESOLVED_WITH_MERGE : STC_OK; + return res.m_merged ? STATUS_DATA_MERGED : STATUS_OK; } -int TrackingSyncSource::deleteItemThrow(SyncItem& item) +SyncMLStatus TrackingSyncSource::deleteItemThrow(SyncItem& item) { const string uid = item.getKey(); deleteItem(uid); m_trackingNode->removeProperty(uid); - return STC_OK; -} - -void TrackingSyncSource::setItemStatusThrow(const char *uid, int status) -{ + return STATUS_OK; } diff --git a/src/core/TrackingSyncSource.h b/src/core/TrackingSyncSource.h index f8be99a5..548565b9 100644 --- a/src/core/TrackingSyncSource.h +++ b/src/core/TrackingSyncSource.h @@ -198,17 +198,15 @@ class TrackingSyncSource : public EvolutionSyncSource virtual void logItem(const string &uid, const string &info, bool debug = false) = 0; virtual void logItem(const SyncItem &item, const string &info, bool debug = false) = 0; - virtual void setItemStatusThrow(const char *key, int status); - private: /* implementations of EvolutionSyncSource callbacks */ virtual void beginSyncThrow(bool needAll, bool needPartial, bool deleteLocal); virtual void endSyncThrow(); - virtual int addItemThrow(SyncItem& item); - virtual int updateItemThrow(SyncItem& item); - virtual int deleteItemThrow(SyncItem& item); + virtual SyncMLStatus addItemThrow(SyncItem& item); + virtual SyncMLStatus updateItemThrow(SyncItem& item); + virtual SyncMLStatus deleteItemThrow(SyncItem& item); boost::shared_ptr<ConfigNode> m_trackingNode; }; diff --git a/src/core/vocl/README b/src/core/vocl/README deleted file mode 100644 index c3f7af7a..00000000 --- a/src/core/vocl/README +++ /dev/null @@ -1,4 +0,0 @@ -The code in this directory is a copy of the Funambol 3.x C++ -client api code, revision sdkcpp_3_0_17. It was forked because -the upstream development broke the vCard 2.1 <-> 3.0 conversion -that SyncEvolution needs. diff --git a/src/core/vocl/VConverter.cpp b/src/core/vocl/VConverter.cpp deleted file mode 100644 index 393bee36..00000000 --- a/src/core/vocl/VConverter.cpp +++ /dev/null @@ -1,314 +0,0 @@ -/** - * Copyright (C) 2003-2006 Funambol - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include "posixadapter.h" - -#include "VConverter.h" -#include "base/util/WString.h" - -namespace vocl { - -VObject* VConverter::parse(wchar_t* buffer) { - - wchar_t *objType = extractObjectType(buffer); - wchar_t *objVersion = extractObjectVersion(buffer); - if(!objType) - return NULL; - - VObject* vo = new VObject(); - vo->setVersion(objVersion); - VProperty *prop; - - wchar_t* buffCopy = new wchar_t[wcslen(buffer) + 1]; - wcscpy(buffCopy, buffer); - - while ( true ) { - prop = readFieldHeader(buffCopy); - if (!prop) { - break; - } - if ( readFieldBody(*vo, buffCopy, prop )) { - // this makes a copy of prop, we still have to free it - vo->addProperty(prop); - } - delete prop; - } - - delete [] buffCopy; buffCopy = NULL; - - return vo; -} - -VProperty* VConverter::readFieldHeader(wchar_t* buffer) { - - wchar_t* headerIndex = NULL; - wchar_t* quotaIndex = NULL; - quotaIndex = wcschr(buffer, '"'); - headerIndex = wcschr(buffer, ':'); - - - if(!headerIndex) - return NULL; - bool quota = false; - // If the header contains a quotation mark, - // then rescan it starting directly after the _quotation mark_ - // (not after the end of the header, as in the original code) - // to find the real end of the header. - // - // The reason for this code apparently is that the simple search above - // might have found a headerIndex which points into the middle of - // the quoted string. - // - // A better solution would be to always scan the header properly. - if(quotaIndex && quotaIndex < headerIndex) { - quota = true; - int len = int(wcslen(buffer)); - for(int i = int(quotaIndex - buffer) + 1; i < len; i++) { - if(buffer[i] == '"') - quota = !quota; - if(buffer[i] == ':' && !quota) { - headerIndex = &buffer[i]; - break; - } - } - } - - if(quota) - return NULL; - - VProperty* prop = new VProperty(NULL); - - wchar_t* header = new wchar_t[wcslen(buffer) + 1]; - buffer[headerIndex - buffer] = '\0'; - wcscpy(header, buffer); - // Shift the remaing string to the front of the buffer. - // Using wcscpy() for that is incorrect because the standard - // does not guarantee in which order bytes are moved! - // wcscpy(buffer, ++headerIndex); - ++headerIndex; - memmove(buffer, headerIndex, (wcslen(headerIndex) + 1) * sizeof(*headerIndex)); - - //if the header is folded (in .ics files) - //we need to remove the folding - wchar_t* headerFolding = NULL; - if((headerFolding = wcsstr(header, TEXT("\n "))) != NULL) { - header[headerFolding - header] = '\0'; - } - - wchar_t seps[] = TEXT(";"); - wchar_t *token; - bool first = true; - - token = wcstok( header, seps ); - while( token != NULL ) { - if (first) { - - wchar_t* group = new wchar_t[wcslen(token) + 1]; - if(extractGroup(token, group)) - prop->addParameter(TEXT("GROUP"), group); - else - delete [] group; group= NULL; - prop->setName(token); - first = false; - } - else { - wchar_t* paramIndex; - paramIndex = wcschr(token, '='); - - if(paramIndex) { - wchar_t* paramName = new wchar_t[wcslen(token) + 1]; - token[paramIndex - token] = '\0'; - wcscpy(paramName, token); - ++paramIndex; - memmove(token, paramIndex, (wcslen(paramIndex) + 1) * sizeof(*paramIndex)); - - wchar_t* paramVal = new wchar_t[wcslen(token) + 1]; - wcscpy(paramVal, token); - prop->addParameter(paramName, paramVal); - - delete [] paramName; paramName = NULL; - delete [] paramVal; paramVal = NULL; - } - else { - prop->addParameter(token,NULL); - } - } - token = wcstok( NULL, seps ); - } - - delete [] header; header = NULL; - delete token; token = NULL; - - return prop; -} - -bool VConverter::readFieldBody(VObject &vo, wchar_t* buffer, VProperty* vprop) { - // old folding (vCard 2.1): folding insert CRLF before _existing_ space - // new MIME folding( vCard 3.0, iCalendar): folding inserts CRLFSP - bool isOldFolding = vo.getVersion() && - !bstrcmp(vo.getVersion(), "2.1"); - bool folding = false; - wchar_t *c = buffer; - int i = 0, j = 0; - wchar_t* value = new wchar_t[wcslen(buffer) + 1]; - - wcscpy(value, TEXT("")); - - if(vprop->equalsEncoding(TEXT("QUOTED-PRINTABLE"))) { - bool afterEqual = false; - while (c[i] != '\0') { - if (c[i] == '\r') { - if (c[i + 1] == '\n') { - if (!afterEqual) { - // end of property after \r\n, - // ignore last two characters and stop - i += 2; - break; - } - } - } else if (c[i] == '\n') { - if (!afterEqual) { - // end of property after single \n, - // ignore last two characters and stop - i += 1; - break; - } - } else if (c[i] == '=') { - afterEqual = true; - } else { - // normal character - afterEqual = false; - } - - value[j] = c[i]; - j++; - i++; - } - } else { - while (c[i] != '\0') { - if(folding) { - if((c[i] == ' ') || c[i] == '\t' ) { - if (isOldFolding) { - value[j] = c[i]; - j++; - } - folding = false; - } - else - if((c[i] != '\r') && (c[i] != '\n')) - break; - } - else { - if((c[i] == '\r') || c[i] == '\n' ) - folding = true; - else { - value[j] = c[i]; - j++; - value[j] = '\0'; - } - } - i++; - } - } - - value[j] = 0; - vprop->setValue(value); - delete [] value; value = NULL; - // wcscpy only valid for non-overlapping buffers. - // This one here can overlap. - // wcscpy(buffer, c+i); - memmove(buffer, c+i, (wcslen(c+i) + 1) * sizeof(*c)); - - return true; -} - -wchar_t* VConverter::extractObjectProperty(wchar_t* buffer, const wchar_t *property, - wchar_t * &buffCopy, size_t &buffCopyLen) { - - // Memory handling in extractObjectType() and - // extractObjectVersion() was broken: - // they allocated a buffer, then returned a pointer into - // parts of this buffer as result. The caller cannot - // free the result in this case. The functions were also - // duplicating the same code. - // - // This partial fix reuses previously allocated - // memory if the function is called a second time. - - size_t len = wcslen(buffer) + 1; - if (buffCopyLen < len) { - if (buffCopy) { - delete [] buffCopy; - } - buffCopy = new wchar_t[len]; - buffCopyLen = len; - } - wcscpy(buffCopy, buffer); - - wchar_t seps[] = TEXT(":\n"); - wchar_t *token; - - token = wcstok( buffCopy, seps ); - while (token != NULL) { - if(!wcscmp(token, TEXT(property))) { - token = wcstok( NULL, seps ); - wchar_t* index = wcschr(token,'\r'); - if(index) - token[index-token] = '\0'; - return token; - } - token = wcstok( NULL, seps ); - } - - return NULL; -} - -wchar_t* VConverter::extractObjectType(wchar_t* buffer) { - static wchar_t* buffCopy; - static size_t buffCopyLen; - - return extractObjectProperty(buffer, "BEGIN", - buffCopy, buffCopyLen); -} - - -wchar_t* VConverter::extractObjectVersion(wchar_t* buffer) { - static wchar_t* buffCopy; - static size_t buffCopyLen; - - return extractObjectProperty(buffer, "VERSION", - buffCopy, buffCopyLen); -} - -bool VConverter::extractGroup(wchar_t* propertyName, wchar_t* propertyGroup) { - - wchar_t* groupIndex; - groupIndex = wcschr(propertyName, '.'); - - if(!groupIndex) - return false; - - propertyName[groupIndex - propertyName] = '\0'; - wcscpy(propertyGroup, propertyName); - wcscpy(propertyName, ++groupIndex); - - return true; -} - -}; diff --git a/src/core/vocl/VConverter.h b/src/core/vocl/VConverter.h deleted file mode 100644 index 5d0357e0..00000000 --- a/src/core/vocl/VConverter.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef INCL_VIRTUAL_CONVERTER -#define INCL_VIRTUAL_CONVERTER - -#include "VObject.h" - -namespace vocl { - -class VConverter{ - -public: - static VObject* parse(char* buffer); - -private: - static VProperty* readFieldHeader(char* buffer); - static bool readFieldBody(VObject &vo, char* buffer, VProperty* property); - - // Extract the parameter of certain properties, e.g. "BEGIN:" or "VERSION:". - // The result is a pointer into buffCopy, which is expected to have - // buffCopyLen wchars and will be reallocated if necessary. - static char* extractObjectProperty(char* buffer, const char *property, - char * &buffCopy, size_t &buffCopyLen); - - // extractObjectType() and extractObjectVersion() contain static buffers, - // copy the result before calling these functions again! - static char* extractObjectType(char* buffer); - static char* extractObjectVersion(char* buffer); - static bool extractGroup(char* propertyName, char* propertyGroup); - -}; - -}; -#endif diff --git a/src/core/vocl/VObject.cpp b/src/core/vocl/VObject.cpp deleted file mode 100644 index b4c285cc..00000000 --- a/src/core/vocl/VObject.cpp +++ /dev/null @@ -1,485 +0,0 @@ -/** - * Copyright (C) 2003-2006 Funambol - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -// this code originally comes from the client library -// and needs some of the internal defines in -// posixadapter.h -#include "posixadapter.h" - -#include "base/util/utils.h" -#include "base/util/WString.h" -#include "base/Log.h" -#include "VObject.h" - -namespace vocl { - -VObject::VObject() { - productID = NULL; - version = NULL; - properties = new ArrayList(); -} - -VObject::~VObject() { - if (productID) { - delete [] productID; productID = NULL; - } - if (version) { - delete [] version; version = NULL; - } - if (properties) { - delete properties; properties = NULL; - } -} - -void VObject::set(wchar_t** p, const wchar_t* v) { - if (*p) { - delete [] *p; - } - *p = (v) ? wstrdup(v) : NULL; -} - -void VObject::setVersion(const wchar_t* ver) { - set(&version, ver); -} - -void VObject::setProdID(const wchar_t* prodID) { - set(&productID, prodID); -} - -wchar_t* VObject::getVersion() { - return version; -} - -wchar_t* VObject::getProdID() { - return productID; -} - -void VObject::addProperty(VProperty* vProp) { - properties->add((ArrayElement&) *vProp); -} - -int VObject::propertiesCount() { - return properties->size(); -} - -bool VObject::removeProperty(int index) { - if(index < 0 || index >= propertiesCount()) - return false; - properties->removeElementAt(index); - return true; -} - -void VObject::removeProperty(const wchar_t* propName) { - for (int i=0; i<properties->size(); i++) { - VProperty *property; - property = (VProperty* )properties->get(i); - if(!wcscmp(property->getName(), propName)) { - properties->removeElementAt(i); - break; - } - } -} - -bool VObject::containsProperty(const wchar_t* propName) { - for (int i=0; i<properties->size(); i++) { - VProperty *property; - property = (VProperty* )properties->get(i); - if(!wcscmp(property->getName(), propName)) { - return true; - } - } - return false; -} - -VProperty* VObject::getProperty(int index) { - return (VProperty*)properties->get(index); -} - -VProperty* VObject::getProperty(const wchar_t* propName) { - for (int i=0; i<properties->size(); i++) { - - VProperty *property; - property = (VProperty* )properties->get(i); - - if(!wcscmp(property->getName(), propName)) { - return property; - } - } - return NULL; -} - -wchar_t* VObject::toString() { - - WString strVObject; - const wchar_t* eof; - - // vcard 2.1 and 3.0 both use \r\n as line ending - eof = TEXT("\r\n"); - - for (int i=0; i<properties->size(); i++) { - VProperty *property; - property = (VProperty*)properties->get(i); - if(property->containsParameter(TEXT("GROUP"))) { - strVObject.append(property->getParameterValue(TEXT("GROUP"))); - strVObject.append(TEXT(".")); - property->removeParameter(TEXT("GROUP")); - } - strVObject.append(property->getName()); - - for(int k=0; k<property->parameterCount(); k++) { - strVObject.append(TEXT(";")); - - wchar_t* paramName = new wchar_t[wcslen(property->getParameter(k))+1]; - wcscpy(paramName, property->getParameter(k)); - - strVObject.append(paramName); - const wchar_t *value = property->getParameterValue(k); - if(value) { - strVObject.append(TEXT("=")); - strVObject.append(value); - } - delete [] paramName; paramName = NULL; - } - - strVObject.append(TEXT(":")); - if(property->getValue()) { - if(property->equalsEncoding(TEXT("BASE64"))) { - wchar_t delim[] = TEXT("\r\n "); - int fold = 76; - int sizeOfValue = int(wcslen(property->getValue())); - int size = sizeOfValue + (int)(sizeOfValue/fold + 2)*int(wcslen(delim)); - int index = 0; - - wchar_t* output = new wchar_t[size + 1]; - wcscpy(output, TEXT("\0")); - - while (index<sizeOfValue) - { - wcscat(output,delim); - wcsncat(output,property->getValue()+index,fold); - index+=fold; - } - - strVObject.append(output); - // the extra empty line is needed because the Bachus-Naur - // specification of vCard 2.1 says so - strVObject.append(eof); - delete [] output; - } - else - strVObject.append(property->getValue()); - } - strVObject.append(eof); - } - - // memory must be free by caller with delete [] - wchar_t *str = new wchar_t[strVObject.length() + 1]; - wcscpy(str, strVObject.c_str()); - return str; -} - -void VObject::insertProperty(VProperty* property) { - - if (propertiesCount() == 0 || wcscmp(getProperty(propertiesCount()-1)->getName(),TEXT("END"))) - addProperty(property); - else { - VProperty* lastProperty = getProperty(TEXT("END")); - removeProperty(TEXT("END")); - addProperty(property); - addProperty(lastProperty); - } -} - -void VObject::addFirstProperty(VProperty* property) { - properties->add(0,(ArrayElement&)*property); -} - -void VObject::removeAllProperies(const wchar_t* propName) { - for(int i = 0, m = propertiesCount(); i < m ; i++) - if(!wcscmp(getProperty(i)->getName(), propName)) { - removeProperty(i); - --i; - --m; - } -} - - -// Patrick Ohly: hack below, see header file - -static int hex2int( wchar_t x ) -{ - return (x >= '0' && x <= '9') ? x - '0' : - (x >= 'A' && x <= 'F') ? x - 'A' + 10 : - (x >= 'a' && x <= 'f') ? x - 'a' + 10 : - 0; -} - -void VObject::toNativeEncoding() -{ - bool is_30 = !wcscmp(getVersion(), TEXT("3.0")); - // line break is encoded with either one or two - // characters on different platforms - const int linebreaklen = wcslen(SYNC4J_LINEBREAK); - - for (int index = propertiesCount() - 1; index >= 0; index--) { - VProperty *vprop = getProperty(index); - wchar_t *name = vprop->getName(); - wchar_t *foreign = vprop->getValue(); - // the native encoding is always shorter than the foreign one - wchar_t *native = new wchar_t[wcslen(foreign) + 1]; - - if (vprop->equalsEncoding(TEXT("QUOTED-PRINTABLE"))) { - int in = 0, out = 0; - wchar_t curr; - - // this is a very crude quoted-printable decoder, - // based on Wikipedia's explanation of quoted-printable - while ((curr = foreign[in]) != 0) { - in++; - if (curr == '=') { - wchar_t values[2]; - values[0] = foreign[in]; - in++; - if (!values[0]) { - // incomplete?! - break; - } - values[1] = foreign[in]; - in++; - if (values[0] == '\r' && values[1] == '\n') { - // soft line break, ignore it - } else { - native[out] = (hex2int(values[0]) << 4) | - hex2int(values[1]); - out++; - - // replace \r\n with \n? - if ( linebreaklen == 1 && - out >= 2 && - native[out - 2] == '\r' && - native[out - 1] == '\n' ) { - native[out - 2] = SYNC4J_LINEBREAK[0]; - out--; - } - - // the conversion to wchar on Windows is - // probably missing here - } - } else { - native[out] = curr; - out++; - } - } - native[out] = 0; - out++; - } else { - wcscpy(native, foreign); - } - - // decode escaped characters after backslash: - // \n is line break only in 3.0 - wchar_t curr; - int in = 0, out = 0; - while ((curr = native[in]) != 0) { - in++; - switch (curr) { - case '\\': - curr = native[in]; - in++; - switch (curr) { - case 'n': - if (is_30) { - // replace with line break - wcsncpy(native + out, SYNC4J_LINEBREAK, linebreaklen); - out += linebreaklen; - } else { - // normal escaped character - native[out] = curr; - out++; - } - break; - case 0: - // unexpected end of string - break; - default: - // just copy next character - native[out] = curr; - out++; - break; - } - break; - case ';': - // Might be field separator, but beware: - // in vCard 2.1 a single, unescaped semicolon is valid in all - // properties which are single values and not structured. - // Some encoders even do that in 3.0, so always accept a literal - // ; as it is in properties which are not multi-value. - if (!wcsicmp(name, "N") || - !wcsicmp(name, "ADR") || - !wcsicmp(name, "ORG")) { - // must replace with something special - // so that we can encode it again in fromNativeEncoding() - native[out] = SEMICOLON_REPLACEMENT; - out++; - } else { - // copy literally - native[out] = ';'; - out++; - } - break; - default: - native[out] = curr; - out++; - } - } - native[out] = 0; - out++; - - // charset handling: - // - doesn't exist at the moment, vCards have to be in ASCII or UTF-8 - // - an explicit CHARSET parameter is removed because its parameter - // value might differ between 2.1 and 3.0 (quotation marks allowed in - // 3.0 but not 2.1) and thus would require extra code to convert it; - // when charsets really get supported this needs to be addressed - wchar_t *charset = vprop->getParameterValue(TEXT("CHARSET")); - if (charset) { - // proper decoding of the value and the property value text - // would go here, for the time being we just remove the - // value - if (_wcsicmp(charset, TEXT("UTF-8")) && - _wcsicmp(charset, TEXT("\"UTF-8\""))) { - // log error("ignoring unsupported charset"); - } - vprop->removeParameter(TEXT("CHARSET")); - } - - vprop->setValue(native); - delete [] native; - } -} - -void VObject::fromNativeEncoding() -{ - bool is_30 = !wcscmp(getVersion(), TEXT("3.0")); - - for (int index = propertiesCount() - 1; index >= 0; index--) { - VProperty *vprop = getProperty(index); - - wchar_t *native = vprop->getValue(); - // in the worst case every comma/linebreak is replaced with - // two characters and each \n with =0D=0A - wchar_t *foreign = new wchar_t[6 * wcslen(native) + 1]; - wchar_t curr; - int in = 0, out = 0; - // line break is encoded with either one or two - // characters on different platforms - const int linebreaklen = wcslen(SYNC4J_LINEBREAK); - - // use backslash for special characters, - // if necessary do quoted-printable encoding - bool doquoted = !is_30 && - wcsstr(native, SYNC4J_LINEBREAK) != NULL; - - if (vprop->equalsEncoding(TEXT("QUOTED-PRINTABLE"))) { - // remove it, recreate if doing 2.1 - vprop->removeParameter(TEXT("ENCODING")); - if (!is_30) { - doquoted = true; - } - } - - // non-ASCII character encountered - bool utf8 = false; - - while ((curr = native[in]) != 0) { - in++; - switch (curr) { - case ',': - if (!is_30) { - // normal character - foreign[out] = curr; - out++; - break; - } - // no break! - case ';': - case '\\': - foreign[out] = '\\'; - out++; - foreign[out] = curr; - out++; - break; - case SEMICOLON_REPLACEMENT: - foreign[out] = ';'; - out++; - break; - default: - bool currIsUTF8 = (unsigned char)curr >= 128; - - if (currIsUTF8) { - utf8 = true; - if (!is_30 && !doquoted) { - // vCard 2.1 defaults to 7-bit; instead of - // overriding that we fall back to quoted-printable - doquoted = true; - } - } - - if (doquoted && - (curr == '=' || currIsUTF8)) { - // escape = and non-ASCII characters - wsprintf(foreign + out, TEXT("=%02X"), (unsigned int)(unsigned char)curr); - out += 3; - } else if (!wcsncmp(native + in - 1, - SYNC4J_LINEBREAK, - linebreaklen)) { - // line break - if (is_30) { - foreign[out] = '\\'; - out++; - foreign[out] = 'n'; - out++; - } else { - wcscpy(foreign + out, TEXT("=0D=0A")); - out += 6; - } - in += linebreaklen - 1; - } else { - foreign[out] = curr; - out++; - } - break; - } - } - foreign[out] = 0; - vprop->setValue(foreign); - delete [] foreign; - if (doquoted) { - // we have used quoted-printable encoding - vprop->addParameter(TEXT("ENCODING"), TEXT("QUOTED-PRINTABLE")); - } - if (utf8 && - !is_30 && - !vprop->getParameterValue("CHARSET")) { - vprop->addParameter("CHARSET", "UTF-8"); - } - } -} - -}; diff --git a/src/core/vocl/VObject.h b/src/core/vocl/VObject.h deleted file mode 100644 index 9c48b749..00000000 --- a/src/core/vocl/VObject.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef INCL_VIRTUAL_OBJECT -#define INCL_VIRTUAL_OBJECT - -#include "VProperty.h" - -namespace vocl { - -class VObject { - -private: - - char* version; - char* productID; - ArrayList* properties; - void set(char**, const char*); - -public: - - VObject(); - ~VObject(); - void setVersion (const char* ver); - void setProdID (const char* prodID); - char* getVersion(); - char* getProdID(); - void addProperty(VProperty* property); - void addProperty(const char *name, const char *value) { VProperty vprop(name, value); addProperty(&vprop); } - void addFirstProperty(VProperty* property); - void insertProperty(VProperty* property); - bool removeProperty(int index); - void removeProperty(const char* propName); - void removeAllProperies(const char* propName); - //removes all properties having name - propName; - bool containsProperty(const char* propName); - int propertiesCount(); - VProperty* getProperty(int index); - VProperty* getProperty(const char* propName); - char* toString(); - - // Patrick Ohly: - // - // Normally the class does not change the encoding - // of properties. That means that users of this class - // have to be prepared to handle e.g. quoted-printable - // encoding of non-ASCII characters or \n as line break - // in vCard 3.0. - // - // This function decodes all property strings into the - // native format. It supports: - // - decoding quoted-printable characters if - // ENCODING=QUOTED-PRINTABLE - // - replacement of \n with a line break and \, with - // single comma if version is 3.0 - // - // It does not support charset conversions, so everything - // has to be UTF-8 to work correctly. - // - // This function does not modify the property parameters, - // so one could convert back into the original format. - // - // Consider this function a hack: at this time it is not - // clear how the class is supposed to handle different - // encodings, but I needed a solution, so here it is. - // - void toNativeEncoding(); - - // - // Converts properties in native format according to - // their parameters. - // - // It only supports: - // - replacement of line breaks and commas (if 3.0) - // - // It does not support any charsets or encoding. - // ENCODING=QUOTED-PRINTABLE will be removed because - // it no longer applies when toNativeEncoding() was - // used before, but the other parameters are preserved: - // this might be good enough to recreate the original - // object. - // - void fromNativeEncoding(); - - /** in native property values this special character separates sub-values in multi-value properties */ - static const char SEMICOLON_REPLACEMENT = '\a'; -}; - -}; - -#endif diff --git a/src/core/vocl/VProperty.cpp b/src/core/vocl/VProperty.cpp deleted file mode 100644 index 932e848d..00000000 --- a/src/core/vocl/VProperty.cpp +++ /dev/null @@ -1,296 +0,0 @@ -/** - * Copyright (C) 2003-2006 Funambol - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include "posixadapter.h" - -#include "base/util/utils.h" -#include "base/util/StringBuffer.h" -#include "VProperty.h" - -namespace vocl { - -VProperty::VProperty(const wchar_t* propname, const wchar_t* propvalue) { - - name = (propname) ? wstrdup(propname) : NULL; - value = (propvalue) ? wstrdup(propvalue) : NULL; - parameters = new ArrayList(); -} - -VProperty::~VProperty() { - - if (name) { - delete [] name; name = NULL; - } - if (value) { - delete [] value; value = NULL; - } - if (parameters) { - delete parameters; parameters = NULL; - } -} - -void VProperty::setName (const wchar_t* s) { - - set(&name, s); -} - -void VProperty::setValue (const wchar_t* s) { - - set(&value, s); -} - -wchar_t* VProperty::getName(wchar_t* buf, int size) { - - if (buf == NULL) { - return name; - } - - if (size >= 0) { - wcsncpy(buf, name, size); - } - else { - wcscpy(buf, name); - } - - return buf; -} - -wchar_t* VProperty::getValue(wchar_t* buf, int size) { - - if (buf == NULL) { - return value; - } - - if (size >= 0) { - wcsncpy(buf, value, size); - } - else { - wcscpy(buf, value); - } - - return buf; -} - -void VProperty::addParameter (const wchar_t* paramName, const wchar_t* paramValue) { - - if(paramName) { - WKeyValuePair *parameter = new WKeyValuePair(paramName, paramValue); - parameters->add((ArrayElement &)*parameter); - - delete parameter; parameter = NULL; - } -} - -void VProperty::removeParameter(const wchar_t* paramName) { - - if (parameters != NULL) { - for (int i=0; i<parameters->size(); i++){ - WKeyValuePair *parameter; - parameter = (WKeyValuePair* )parameters->get(i); - if(!wcscmp(parameter->getKey(), paramName)) { - parameters->removeElementAt(i); - break; - } - } - } -} - -void VProperty::removeParameter(int index) { - parameters->removeElementAt(index); -} - -bool VProperty::containsParameter(const wchar_t* paramName) { - - if (parameters != NULL) { - for (int i=0; i<parameters->size(); i++){ - WKeyValuePair *parameter; - parameter = (WKeyValuePair* )parameters->get(i); - if(!wcscmp(parameter->getKey(), paramName)){ - return true; - } - } - } - - return false; -} -wchar_t* VProperty::getParameterValue(const wchar_t* paramName) { - - if (parameters != NULL) { - for (int i=0; i<parameters->size(); i++) { - WKeyValuePair *parameter; - parameter = (WKeyValuePair* )parameters->get(i); - if(!wcscmp(parameter->getKey(), paramName)) - return ((wchar_t *)parameter->getValue()); - } - } - - return NULL; -} -wchar_t* VProperty::getParameterValue(int index) { - - if (parameters != NULL) { - WKeyValuePair *parameter; - parameter = (WKeyValuePair*)parameters->get(index); - return parameter ? (wchar_t *)parameter->getValue() : NULL; - } - - return NULL; -} - -void VProperty::set(wchar_t** p, const wchar_t* v) { - - if (*p) { - delete [] *p; - } - *p = (v) ? wstrdup(v) : NULL; -} - -ArrayElement* VProperty::clone() { - - if(name) { - - VProperty *cloneProperty = new VProperty(name); - - if(value) - cloneProperty->setValue(value); - - if (parameters != NULL) { - for (int i=0; i<parameters->size(); i++) { - WKeyValuePair* parameterCopy; - parameterCopy = (WKeyValuePair*)parameters->get(i)->clone(); - cloneProperty->addParameter(parameterCopy->getKey(), parameterCopy->getValue()); - delete parameterCopy; - } - } - return cloneProperty; - } - return NULL; -} - -int VProperty::parameterCount() { - - return parameters->size(); -} - -wchar_t* VProperty::toString() { - - wchar_t *propertyString = new wchar_t[VPROPETY_BUFFER]; - if (name!=NULL){ - wcscpy(propertyString, name); - if(parameterCount()>0) { - for (int i=0; i<parameters->size(); i++) { - WKeyValuePair *parameter; - parameter = (WKeyValuePair*)parameters->get(i); - if(parameter->getKey()!= NULL) { - wcscat(propertyString, TEXT(";")); - wcscat(propertyString, parameter->getKey()); - } - if(parameter->getValue()!= NULL) { - wcscat(propertyString, TEXT("=")); - wcscat(propertyString, parameter->getValue()); - } - } - } - wcscat(propertyString, TEXT(":")); - if(value!=NULL) { - wcscat(propertyString, value); - } - } - return propertyString; -} - -wchar_t* VProperty::getParameter(int index){ - - WKeyValuePair *parameter; - parameter = (WKeyValuePair*)parameters->get(index); - return (wchar_t *)parameter->getKey(); -} - -bool VProperty::equalsEncoding(const wchar_t* encoding) { - - if ((encoding != NULL) && ((containsParameter(TEXT("ENCODING")) && - !wcscmp(getParameterValue(TEXT("ENCODING")),encoding)) || - containsParameter(encoding))) - return true; - return false; -} - -wchar_t* VProperty::getPropComponent(int i) { - - - if (!getValue() || !wcscmp(getValue(),TEXT(""))) - return NULL; - - wchar_t *value = new wchar_t[wcslen(getValue()) + 1]; - wchar_t* component = new wchar_t[wcslen(getValue()) + 1]; - - wcscpy(value, getValue()); - wchar_t* componentIndex; - int j=0; - - while (j < i) { - componentIndex = wcschr(value, ';'); - if(componentIndex) { - value[componentIndex - value] = 0; - wcscpy(component, value); - wcscpy(value, ++componentIndex); - j++; - } - else - if(j<i-1) - return NULL; - else - return value; - } - - delete [] value; value = NULL; - if(component && wcscmp(component, TEXT(""))) - return component; - else - return NULL; -} - -bool VProperty::isType(const wchar_t* type) { - if(containsParameter(type)) - return true; - - for (int paramindex = 0; - paramindex < parameterCount(); - paramindex++) { - wchar_t *value = getParameterValue(paramindex); - wchar_t *param = getParameter(paramindex); - if (value && param && !strcasecmp(param, "TYPE")) { - wchar_t seps[] = TEXT(","); - wchar_t* token; - - StringBuffer buff(value); - - token = wcstok((char *)buff.c_str(), seps); - while( token != NULL ) { - if(!wcscmp(type, token)) - return true; - token = wcstok( NULL, seps ); - } - } - } - - return false; -} - -}; diff --git a/src/core/vocl/VProperty.h b/src/core/vocl/VProperty.h deleted file mode 100644 index 212e63d1..00000000 --- a/src/core/vocl/VProperty.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright (C) 2005-2006 Funambol - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#ifndef INCL_VIRTUAL_PROPERTY -#define INCL_VIRTUAL_PROPERTY - -#include "base/fscapi.h" -#include "base/util/WKeyValuePair.h" -#include "base/util/ArrayList.h" - -namespace vocl { - -#define VPROPETY_BUFFER 500 - -class VProperty : public ArrayElement { - -private: - - char* name; - char* value; - void set(char** p, const char* v); - ArrayList* parameters; - - public: - - VProperty(const char* propName , const char* propValue = NULL); - ~VProperty(); - ArrayElement* clone(); - void setName (const char* name); - void setValue (const char* value); - char* getName(char* buf = NULL, int size = -1); - char* getValue(char* buf = NULL, int size = -1); - void addParameter(const char* paramName, const char* paramValue); - void removeParameter(const char* paramName); - void removeParameter(int index); - bool containsParameter(const char* paramName); - // Warning: the name does not always uniquely identify - // the parameter, some of them may occur multiple times. - // Use getParameterValue(int index) to get the value which - // corresponds to a specific parameter. - char* getParameterValue(const char* paramName); - char* getParameterValue(int index); - char* getParameter(int index); - int parameterCount(); - bool equalsEncoding(const char* encoding); - char* getPropComponent(int i); - bool isType(const char* type); - char* toString(); - - }; - -}; - -#endif diff --git a/src/core/vocl/posixadapter.h b/src/core/vocl/posixadapter.h deleted file mode 100644 index b54f8a19..00000000 --- a/src/core/vocl/posixadapter.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2005-2006 Funambol - * Author Patrick Ohly - */ - -#ifndef INCL_POSIX_ADAPTER -#define INCL_POSIX_ADAPTER - - -/* - * POSIX environment, configured and compiled with automake/autoconf - */ - -#include <config.h> -#include <string.h> -#include <wchar.h> -#include <stdlib.h> -#include <ctype.h> -#include <stdio.h> -#include <time.h> -#include <stdarg.h> - -#include <string> -#include <cwchar> -#include <iostream> - -// For ntoh functions -#include <netinet/in.h> - -// Cygwin version of gcc does have these builtin -#ifndef __CYGWIN__ -# define __declspec(x) -# define __cdecl -#endif - -//#ifdef ENABLE_NLS -//# include <libintl.h> -//# define TEXT(String) gettext (String) -//#else -//# define TEXT(String) (String) -//# endif -#define TEXT(_x) _x -#define CHR(_x) _x -#define T(_x) _x - -#define EXTRA_SECTION_00 -#define EXTRA_SECTION_01 -#define EXTRA_SECTION_02 -#define EXTRA_SECTION_03 -#define EXTRA_SECTION_04 -#define EXTRA_SECTION_05 -#define EXTRA_SECTION_06 - -#define BOOL int -#define TRUE 1 -#define FALSE 0 - -#define SYNC4J_LINEBREAK "\n" - -/* map wchar_t and its functions back to standard functions */ -#undef wchar_t -#define wchar_t char -#undef BCHAR -typedef char BCHAR; -typedef char WCHAR; - -#define bsprintf sprintf - -#define bstrlen strlen -#define bstrcpy strcpy -#define bstrcat strcat -#define bstrstr strstr -#define bstrchr strchr -#define bstrrchr strrchr -#define bscanf scanf -#define bstrcmp strcmp -#define bstricmp _stricmp -#define bstrncpy strncpy -#define bstrncmp strncmp -#define bstrtol strtol -#define bstrtoul strtoul - -#define wsprintf sprintf -#define _wfopen fopen -#define wprintf printf -#define fwprintf fprintf -#define wsprintf sprintf -#define swprintf sprintf -#define wcscpy strcpy -#define wcsncpy strncpy -#define wcsncmp strncmp -#define wcslen strlen -#define wcstol strtol -#define wcstoul strtoul -#define wcsstr strstr -#define wcscmp strcmp -#define wcstok strtok -inline char towlower(char x) { return tolower(x); } -inline char towupper(char x) { return toupper(x); } -#define wmemmove memmove -#define wmemcpy memcpy -#define wmemcmp memcmp -#define wmemset memset -#define wcschr strchr -#define wcsrchr strrchr -#define wcscat strcat -#define wcsncat strncat -#define _wtoi atoi -#define wcstod strtod -#define wcsicmp strcasecmp -#define _wcsicmp strcasecmp -#define _stricmp strcasecmp - -/* some of the code compares NULL against integers, which - fails if NULL is defined as (void *)0 */ -#undef NULL -#define NULL 0 - -template <class T> T min(T x, T y) { return x < y ? x : y; } -template <class T> T max(T x, T y) { return x > y ? x : y; } - -#endif - diff --git a/src/core/vocl/vcardconverter.cpp b/src/core/vocl/vcardconverter.cpp deleted file mode 100644 index c17b177a..00000000 --- a/src/core/vocl/vcardconverter.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2003-2006 Funambol - */ - -/** - * This program reads one vcard from the file - * given as first parameter and applies certain - * conversions to it. - * - * The content of the file has to be ASCII or - * UTF-8 encoded. - */ - -#include <stdio.h> -#include <memory> - -#include "posixadapter.h" -#include "VConverter.h" -#include "base/util/utils.h" - -using namespace vocl; - -// very simply auto_ptr for arrays -template <class T> class auto_array { - T *m_array; - public: - auto_array(T *array = 0) : m_array(array) {} - ~auto_array() { if (m_array) delete [] m_array; } - - void operator = (T *array) { - if (m_array) delete [] m_array; - m_array = array; - } - operator T * () { return m_array; } - T *get() { return m_array; } - T &operator [] (int index) { return m_array[index]; } -}; - -int main( int argc, char **argv ) -{ - char *sep = TEXT("--------------- %s -----------------------\n"); - char *sep2 = TEXT("-----------------------------------------------------------\n"); - - if (argc != 2) { - fprintf(stdout, "usage: %s <vcard file>\n", argv[0]); - return 1; - } - - // read as char * - char *buffer; - size_t len; - if (!readFile(argv[1], &buffer, &len, true)) { - fprintf(stdout, "%s: reading failed", argv[1]); - } - auto_array<char> vcard(buffer); - - // convert to wchar_t - auto_array<wchar_t> wvcard(toWideChar(vcard)); - fwprintf(stdout, sep, TEXT("original vcard")); - fwprintf(stdout, TEXT("%s\n"), wvcard.get()); - fwprintf(stdout, sep2); - fwprintf(stdout, TEXT("\n")); - - // parse it - std::auto_ptr<VObject> vobj(VConverter::parse(wvcard)); - if (vobj.get() == 0) { - fprintf(stdout, "VConverter::parse()failed\n"); - return 1; - } - vobj->toNativeEncoding(); - - VProperty *fileas = vobj->getProperty(TEXT("X-EVOLUTION-FILE-AS")); - VProperty *n = vobj->getProperty(TEXT("FN")); - fwprintf(stdout, - TEXT("version: %s\nprodid: %s\nfull name: %s\nfile-as: %s\n\n"), - vobj->getVersion(), - vobj->getProdID(), - n ? n->getValue() : TEXT("<not set>"), - fileas ? fileas->getValue() : TEXT("<not set>")); - - // convert into the other version, then back again - wchar_t *versions[2]; - if (!wcscmp(vobj->getVersion(), TEXT("3.0"))) { - versions[0] = TEXT("2.1"); - versions[1] = TEXT("3.0"); - } else { - versions[0] = TEXT("3.0"); - versions[1] = TEXT("2.1"); - } - for (int index = 0; index < 2; index++) { - vobj->setVersion(versions[index]); - VProperty *vprop = vobj->getProperty(TEXT("VERSION")); - - for (int property = vobj->propertiesCount() - 1; - property >= 0; - property--) { - VProperty *vprop = vobj->getProperty(property); - - // replace 3.0 ENCODING=B with 2.1 ENCODING=BASE64 and vice versa - char *encoding = vprop->getParameterValue("ENCODING"); - if (encoding && - (!wcsicmp(TEXT("B"), encoding) || !wcsicmp(TEXT("BASE64"), encoding))) { - vprop->removeParameter("ENCODING"); - vprop->addParameter("ENCODING", - !wcscmp(versions[index], TEXT("2.1")) ? - "BASE64" : "b"); - } - } - - vprop->setValue(versions[index]); - vobj->fromNativeEncoding(); - wvcard = vobj->toString(); - vobj->toNativeEncoding(); - fwprintf(stdout, sep, versions[index]); - fwprintf(stdout, TEXT("%s\n"), wvcard.get()); - fwprintf(stdout, sep2); - fwprintf(stdout, TEXT("\n")); - } - -#if 0 - // convert into validated contact - vCardConverter converter; - converter.setSource(wvcard); - Contact *contactPtr; - long errorCode; - if (!converter.convert(lastErrorMsg, &errorCode)) { - fwprintf(stdout, TEXT("converter failed: %s (%ld)\n"), lastErrorMsg, errorCode); - return 1; - } - converter.getContact(&contactPtr); - std::auto_ptr<Contact> contact(contactPtr); - wvcard = contact->toString(); - fwprintf(stdout, sep, TEXT("after parsing")); - fwprintf(stdout, TEXT("%s\n"), wvcard.get()); - fwprintf(stdout, sep2); - fwprintf(stdout, TEXT("\n")); - - // let's see how the Contact class interprets the properties - Name *name = contact->getName(); - vCardProperty *displayname = name->getDisplayName(); - fwprintf(stdout, - TEXT("display name\nencoding: %s\ncharset: %s\nlanguage: %s\nvalue: %s\n\n"), - displayname->getEncoding(), - displayname->getCharset(), - displayname->getLanguage(), - displayname->getValue()); -#endif - - return 0; -} - - diff --git a/src/syncevolution.cpp b/src/syncevolution.cpp index ea812681..eb408cd9 100644 --- a/src/syncevolution.cpp +++ b/src/syncevolution.cpp @@ -4,9 +4,6 @@ #include <config.h> #include <stddef.h> - -#include <spds/spdsutils.h> - #include <iostream> #include <memory> using namespace std; @@ -67,7 +64,6 @@ int main( int argc, char **argv ) g_type_init(); #endif - resetError(); setvbuf(stderr, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); |