diff options
author | Michele Calgaro <michele.calgaro@yahoo.it> | 2020-09-11 14:38:47 +0900 |
---|---|---|
committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2020-09-11 14:38:47 +0900 |
commit | 884c8093d63402a1ad0b502244b791e3c6782be3 (patch) | |
tree | a600d4ab0d431a2bdfe4c15b70df43c14fbd8dd0 /debian/opensync/opensync-0.22/formats/vformats-xml/xml-support.c | |
parent | 14e1aa2006796f147f3f4811fb908a6b01e79253 (diff) | |
download | extra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.tar.gz extra-dependencies-884c8093d63402a1ad0b502244b791e3c6782be3.zip |
Added debian extra dependency packages.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'debian/opensync/opensync-0.22/formats/vformats-xml/xml-support.c')
-rw-r--r-- | debian/opensync/opensync-0.22/formats/vformats-xml/xml-support.c | 406 |
1 files changed, 406 insertions, 0 deletions
diff --git a/debian/opensync/opensync-0.22/formats/vformats-xml/xml-support.c b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-support.c new file mode 100644 index 00000000..f1583bb8 --- /dev/null +++ b/debian/opensync/opensync-0.22/formats/vformats-xml/xml-support.c @@ -0,0 +1,406 @@ +/* + * xml - A plugin for xml objects for the opensync framework + * Copyright (C) 2004-2005 Armin Bauer <armin.bauer@opensync.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "opensync/opensync.h" +#include "opensync/opensync_time_internals.h" +#include "xml-support.h" +#include <glib.h> + +static char *osxml_prepare_time(const char *content, xmlNode *node) { + + osync_trace(TRACE_ENTRY, "%s(%s, %p)", __func__, content, node); + + int tzoffset = 0; + char *time = NULL; + struct tm *ttm = NULL; + + + if (!osync_time_isutc(content)) { + time = osync_time_tzlocal2utc(node, (char *) node->name); + if (!time) { + ttm = osync_time_vtime2tm(content); + tzoffset = osync_time_timezone_diff(ttm); + time = osync_time_vtime2utc(content, tzoffset); + g_free(ttm); + } + } + + if (!time) + time = g_strdup(content); + + osync_trace(TRACE_EXIT, "%s: %s", __func__, time); + return time; +} + +static osync_bool osxml_compare_time(xmlNode *leftnode, xmlNode *rightnode) { + + osync_trace(TRACE_ENTRY, "%s(%s(%p), %s(%p))", __func__, leftnode->name, leftnode, rightnode->name, rightnode); + int ret = 0; + char *left = NULL, *right = NULL; + char *leftcontent = osxml_find_node(leftnode, "Content"); + char *rightcontent = osxml_find_node(rightnode, "Content"); + + osync_trace(TRACE_SENSITIVE, "time compare - left: %s right: %s", leftcontent, rightcontent); + + if (osync_time_isutc(leftcontent) != osync_time_isutc(rightcontent)) { + left = osxml_prepare_time(leftcontent, leftnode); + right = osxml_prepare_time(rightcontent, rightnode); + + g_free(leftcontent); + g_free(rightcontent); + + osync_trace(TRACE_SENSITIVE, "AFTER convert - left: %s right: %s", left, right); + } else { + left = leftcontent; + right = rightcontent; + } + + ret = strcmp(left, right); + + g_free(left); + g_free(right); + + if (ret) { + osync_trace(TRACE_EXIT, "%s: FALSE", __func__); + return FALSE; + } + + osync_trace(TRACE_EXIT, "%s: TRUE", __func__); + return TRUE; + +} + +static osync_bool osxml_compare_node(xmlNode *leftnode, xmlNode *rightnode) +{ + osync_trace(TRACE_ENTRY, "%s(%p:%s, %p:%s)", __func__, leftnode, leftnode->name, rightnode, rightnode->name); + + if (strcmp((char*)leftnode->name, (char*)rightnode->name)) { + osync_trace(TRACE_EXIT, "%s: FALSE: Different Name", __func__); + return FALSE; + } + + leftnode = leftnode->children; + rightnode = rightnode->children; + xmlNode *rightstartnode = rightnode; + + if (!leftnode && !rightnode) { + osync_trace(TRACE_EXIT, "%s: TRUE. Both 0", __func__); + return TRUE; + } + + if (!leftnode || !rightnode) { + osync_trace(TRACE_EXIT, "%s: FALSE. One 0", __func__); + return FALSE; + } + + do { + if (!strcmp("UnknownParam", (char*)leftnode->name)) + continue; + if (!strcmp("Order", (char*)leftnode->name)) + continue; + rightnode = rightstartnode; + char *leftcontent = (char*)xmlNodeGetContent(leftnode); + + do { + if (!strcmp("UnknownParam", (char*)rightnode->name)) + continue; + + osync_trace(TRACE_INTERNAL, "leftnode %s, rightnode %s", leftnode->name, rightnode->name); + + /* Compare only nodes with same name. Skip if + * the names are different + */ + if (xmlStrcmp(leftnode->name, rightnode->name)) + continue; + + char *rightcontent = (char*)xmlNodeGetContent(rightnode); + + osync_trace(TRACE_SENSITIVE, "leftcontent %s, rightcontent %s\n", leftcontent, rightcontent); + + if (leftcontent == rightcontent) { + g_free(rightcontent); + goto next; + } + + /* We compare the striped content to work around bugs in + * applications like evo2 which always strip the content + * and would therefore cause conflicts. This change should not break + * anything since it does not touch the actual content */ + char *strip_right = g_strstrip(g_strdup(rightcontent)); + char *strip_left = g_strstrip(g_strdup(leftcontent)); + if (!strcmp(strip_left, strip_right)) { + g_free(strip_right); + g_free(strip_left); + g_free(rightcontent); + goto next; + } + g_free(strip_right); + g_free(strip_left); + + if (!leftcontent || !rightcontent) { + osync_trace(TRACE_EXIT, "%s: One is empty", __func__); + return FALSE; + } + + /* Workaround for palm-sync. palm-sync is not able to set a correct Completed date-timestamp so ignore value (objtype: todo) */ + if (!strcmp("Completed", (char*)rightnode->name) && !strcmp("Completed",(char*)leftnode->name)) { + if ((leftcontent && rightcontent) || (!leftcontent && !rightcontent)) { + osync_trace(TRACE_INTERNAL, "PALM-SYNC workaround active!"); + g_free(rightcontent); + goto next; + } + } + + + g_free(rightcontent); + + if ((!strcmp("DateStarted", (char*)rightnode->name) && !strcmp("DateStarted", (char*)leftnode->name)) + || (!strcmp("DateEnd", (char*)rightnode->name) && !strcmp("DateEnd", (char*)leftnode->name))) { + + if (osxml_compare_time(leftnode, rightnode)) + goto next; + } + + /* compare child nodes again .... */ + if (rightnode->type == XML_ELEMENT_NODE && osxml_compare_node(rightnode, leftnode)) + goto next; + + + } while ((rightnode = rightnode->next)); + osync_trace(TRACE_EXIT, "%s: Could not match one", __func__); + g_free(leftcontent); + return FALSE; + next:; + g_free(leftcontent); + } while ((leftnode = leftnode->next)); + + osync_trace(TRACE_EXIT, "%s: TRUE", __func__); + return TRUE; +} + +OSyncConvCmpResult osxml_compare(xmlDoc *leftinpdoc, xmlDoc *rightinpdoc, OSyncXMLScore *scores, int default_score, int treshold) +{ + osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, leftinpdoc, rightinpdoc, scores); + int z = 0, i = 0, n = 0; + int res_score = 0; + + xmlDoc *leftdoc = xmlCopyDoc(leftinpdoc, TRUE); + xmlDoc *rightdoc = xmlCopyDoc(rightinpdoc, TRUE); + + osync_trace(TRACE_INTERNAL, "Comparing given score list"); + while (scores && scores[z].path) { + OSyncXMLScore *score = &scores[z]; + z++; + xmlXPathObject *leftxobj = osxml_get_nodeset(leftdoc, score->path); + xmlXPathObject *rightxobj = osxml_get_nodeset(rightdoc, score->path); + + xmlNodeSet *lnodes = leftxobj->nodesetval; + xmlNodeSet *rnodes = rightxobj->nodesetval; + + int lsize = (lnodes) ? lnodes->nodeNr : 0; + int rsize = (rnodes) ? rnodes->nodeNr : 0; + osync_trace(TRACE_INTERNAL, "parsing next path %s", score->path); + + if (!score->value) { + for (i = 0; i < lsize; i++) { + xmlUnlinkNode(lnodes->nodeTab[i]); + xmlFreeNode(lnodes->nodeTab[i]); + lnodes->nodeTab[i] = NULL; + } + + for (n = 0; n < rsize; n++) { + xmlUnlinkNode(rnodes->nodeTab[n]); + xmlFreeNode(rnodes->nodeTab[n]); + rnodes->nodeTab[n] = NULL; + } + } else { + for (i = 0; i < lsize; i++) { + if (!lnodes->nodeTab[i]) + continue; + for (n = 0; n < rsize; n++) { + if (!rnodes->nodeTab[n]) + continue; + osync_trace(TRACE_INTERNAL, "cmp %i:%s (leftcontent), %i:%s (rightcontent)", i, lnodes->nodeTab[i]->name, + n, rnodes->nodeTab[n]->name); + osync_trace(TRACE_SENSITIVE, "cmp %i:%s (%s), %i:%s (%s)\n", i, lnodes->nodeTab[i]->name, osxml_find_node(lnodes->nodeTab[i], + "Content"), n, rnodes->nodeTab[n]->name, osxml_find_node(rnodes->nodeTab[n], "Content")); + + /* + if ((!strcmp("DateStarted", lnodes->nodeTab[i]->name) && !strcmp("DateStarted", rnodes->nodeTab[n]->name)) + || (!strcmp("DateEnd", lnodes->nodeTab[i]->name) && !strcmp("DateEnd", rnodes->nodeTab[n]->name))) { + */ + + if (osxml_compare_node(lnodes->nodeTab[i], rnodes->nodeTab[n])) { + osync_trace(TRACE_INTERNAL, "Adding %i for %s", score->value, score->path); + res_score += score->value; + xmlUnlinkNode(lnodes->nodeTab[i]); + xmlFreeNode(lnodes->nodeTab[i]); + lnodes->nodeTab[i] = NULL; + xmlUnlinkNode(rnodes->nodeTab[n]); + xmlFreeNode(rnodes->nodeTab[n]); + rnodes->nodeTab[n] = NULL; + goto next; + } + } + osync_trace(TRACE_INTERNAL, "Subtracting %i for %s", score->value, score->path); + res_score -= score->value; + next:; + } + for(i = 0; i < rsize; i++) { + if (!rnodes->nodeTab[i]) + continue; + res_score -= score->value; + } + } + + xmlXPathFreeObject(leftxobj); + xmlXPathFreeObject(rightxobj); + } + + xmlXPathObject *leftxobj = osxml_get_nodeset(leftdoc, "/*/*"); + xmlXPathObject *rightxobj = osxml_get_nodeset(rightdoc, "/*/*"); + + xmlNodeSet *lnodes = leftxobj->nodesetval; + xmlNodeSet *rnodes = rightxobj->nodesetval; + + // Check if nodeTab actually exists (for example vnote stuff would crash otherwise...) + if (lnodes->nodeTab && rnodes->nodeTab) { + // WORKAROUND - FIXME + // if nodeTab[0] is an Event or Todo we need a new node structure (/*/*/*) + + if ((!strcmp((char*)lnodes->nodeTab[0]->name, "Event") && \ + !strcmp((char*)rnodes->nodeTab[0]->name, "Event")) || \ + (!strcmp((char*)lnodes->nodeTab[0]->name, "Todo") && \ + !strcmp((char*)rnodes->nodeTab[0]->name, "Todo"))) { + + xmlXPathFreeObject(leftxobj); + xmlXPathFreeObject(rightxobj); + + leftxobj = osxml_get_nodeset(leftdoc, "/*/*/*"); + rightxobj = osxml_get_nodeset(rightdoc, "/*/*/*"); + + lnodes = leftxobj->nodesetval; + rnodes = rightxobj->nodesetval; + + } + } + + int lsize = (lnodes) ? lnodes->nodeNr : 0; + int rsize = (rnodes) ? rnodes->nodeNr : 0; + + osync_trace(TRACE_INTERNAL, "Comparing remaining list"); + osync_bool same = TRUE; + for(i = 0; i < lsize; i++) { + for (n = 0; n < rsize; n++) { + if (!rnodes->nodeTab[n]) + continue; + osync_trace(TRACE_INTERNAL, "cmp %i:%s (leftcontent), %i:%s (rightcontent)", i, lnodes->nodeTab[i]->name, + n, rnodes->nodeTab[n]->name); + osync_trace(TRACE_SENSITIVE, "cmp %i:%s (%s), %i:%s (%s)\n", i, lnodes->nodeTab[i]->name, osxml_find_node(lnodes->nodeTab[i], + "Content"), n, rnodes->nodeTab[n]->name, osxml_find_node(rnodes->nodeTab[n], "Content")); + + if ((!strcmp("DateStarted", (char *) lnodes->nodeTab[i]->name) && !strcmp("DateStarted", (char *) rnodes->nodeTab[n]->name)) + || (!strcmp("DateEnd", (char *) lnodes->nodeTab[i]->name) && !strcmp("DateEnd", (char *) rnodes->nodeTab[n]->name))) { + + if (osxml_compare_time(lnodes->nodeTab[i], rnodes->nodeTab[n])) { + xmlUnlinkNode(lnodes->nodeTab[i]); + xmlFreeNode(lnodes->nodeTab[i]); + lnodes->nodeTab[i] = NULL; + xmlUnlinkNode(rnodes->nodeTab[n]); + xmlFreeNode(rnodes->nodeTab[n]); + rnodes->nodeTab[n] = NULL; + osync_trace(TRACE_INTERNAL, "Adding %i", default_score); + res_score += default_score; + goto next2; + } + } + + if (osxml_compare_node(lnodes->nodeTab[i], rnodes->nodeTab[n])) { + xmlUnlinkNode(lnodes->nodeTab[i]); + xmlFreeNode(lnodes->nodeTab[i]); + lnodes->nodeTab[i] = NULL; + xmlUnlinkNode(rnodes->nodeTab[n]); + xmlFreeNode(rnodes->nodeTab[n]); + rnodes->nodeTab[n] = NULL; + osync_trace(TRACE_INTERNAL, "Adding %i", default_score); + res_score += default_score; + goto next2; + } + } + osync_trace(TRACE_INTERNAL, "Subtracting %i", default_score); + res_score -= default_score; + + // XXX Find a better way to workaroudn the problem of ignoring without unlinking nodes. + if (!strcmp("Timezone", (char *) lnodes->nodeTab[i]->name)) + osync_trace(TRACE_INTERNAL, "Workaround for Timezone field. We ignore it but don't unlink it from XML"); + else + same = FALSE; + + //goto out; + next2:; + } + + for(i = 0; i < lsize; i++) { + if (!lnodes->nodeTab[i]) + continue; + osync_trace(TRACE_INTERNAL, "left remaining: %s", lnodes->nodeTab[i]->name); + + // XXX Find a better way to workaroudn the problem of ignoring without unlinking nodes. + if (!strcmp("Timezone", (char *) lnodes->nodeTab[i]->name)) + osync_trace(TRACE_INTERNAL, "Workaround for Timezone field. We ignore it but don't unlink it from XML"); + else + same = FALSE; + + goto out; + } + + for(i = 0; i < rsize; i++) { + if (!rnodes->nodeTab[i]) + continue; + osync_trace(TRACE_INTERNAL, "right remaining: %s", rnodes->nodeTab[i]->name); + + // XXX Find a better way to workaroudn the problem of ignoring without unlinking nodes. + if (!strcmp("Timezone", (char *) rnodes->nodeTab[i]->name)) + osync_trace(TRACE_INTERNAL, "Workaround for Timezone field. We ignore it but don't unlink it from XML"); + else + same = FALSE; + + goto out; + } + out: + xmlXPathFreeObject(leftxobj); + xmlXPathFreeObject(rightxobj); + + xmlFreeDoc(leftdoc); + xmlFreeDoc(rightdoc); + + osync_trace(TRACE_INTERNAL, "Result is: %i, Treshold is: %i", res_score, treshold); + if (same) { + osync_trace(TRACE_EXIT, "%s: SAME", __func__); + return CONV_DATA_SAME; + } + if (res_score >= treshold) { + osync_trace(TRACE_EXIT, "%s: SIMILAR", __func__); + return CONV_DATA_SIMILAR; + } + osync_trace(TRACE_EXIT, "%s: MISMATCH", __func__); + return CONV_DATA_MISMATCH; +} + |