OpenSync  0.22
opensync_xml.c
1 /*
2  * xml - A plugin for xml objects for the opensync framework
3  * Copyright (C) 2004-2005 Armin Bauer <armin.bauer@opensync.org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  */
20 
21 #include "opensync.h"
22 #include "opensync_internals.h"
23 
24 xmlNode *osxml_node_add_root(xmlDoc *doc, const char *name)
25 {
26  doc->children = xmlNewDocNode(doc, NULL, (xmlChar*)name, NULL);
27  return doc->children;
28 }
29 
30 xmlNode *osxml_node_get_root(xmlDoc *doc, const char *name, OSyncError **error)
31 {
32  xmlNode *cur = xmlDocGetRootElement(doc);
33  if (!cur) {
34  osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to get xml root element");
35  return NULL;
36  }
37 
38  if (xmlStrcmp((cur)->name, (const xmlChar *) name)) {
39  osync_error_set(error, OSYNC_ERROR_GENERIC, "Wrong xml root element");
40  return NULL;
41  }
42 
43  cur = (cur)->xmlChildrenNode;
44  return cur;
45 }
46 
47 void osxml_node_set(xmlNode *node, const char *name, const char *data, OSyncXMLEncoding encoding)
48 {
49  if (name)
50  xmlNodeSetName(node, (xmlChar*)name); //FIXME Free previous name?
51 
52  if (data)
53  xmlNewTextChild(node, NULL, (xmlChar*)"Content", (xmlChar*)data);
54 }
55 
56 xmlNode *osxml_node_add(xmlNode *parent, const char *name, const char *data)
57 {
58  if (!data)
59  return NULL;
60  if (strlen(data) == 0)
61  return NULL;
62  xmlNode *node = xmlNewTextChild(parent, NULL, (xmlChar*)name, (xmlChar*)data);
63  return node;
64 }
65 
66 void osxml_node_add_property(xmlNode *parent, const char *name, const char *data)
67 {
68  xmlNewProp(parent, (xmlChar*)name, (xmlChar*)data);
69 }
70 
71 void osxml_node_mark_unknown(xmlNode *parent)
72 {
73  if (!xmlHasProp(parent, (xmlChar*)"Type"))
74  xmlNewProp(parent, (xmlChar*)"Type", (xmlChar*)"Unknown");
75 }
76 
77 void osxml_node_remove_unknown_mark(xmlNode *node)
78 {
79  xmlAttr *attr = xmlHasProp(node, (xmlChar*)"Type");
80  if (!attr)
81  return;
82  xmlRemoveProp(attr);
83 }
84 
85 xmlNode *osxml_get_node(xmlNode *parent, const char *name)
86 {
87  xmlNode *cur = (parent)->xmlChildrenNode;
88  while (cur) {
89  if (!xmlStrcmp(cur->name, (const xmlChar *)name))
90  return cur;
91  cur = cur->next;
92  }
93  return NULL;
94 }
95 
96 char *osxml_find_node(xmlNode *parent, const char *name)
97 {
98  return (char*)xmlNodeGetContent(osxml_get_node(parent, name));
99 }
100 
101 xmlXPathObject *osxml_get_nodeset(xmlDoc *doc, const char *expression)
102 {
103  xmlXPathContext *xpathCtx = NULL;
104  xmlXPathObject *xpathObj = NULL;
105 
106  /* Create xpath evaluation context */
107  xpathCtx = xmlXPathNewContext(doc);
108  if(xpathCtx == NULL) {
109  fprintf(stderr,"Error: unable to create new XPath context\n");
110  return NULL;
111  }
112 
113  /* Evaluate xpath expression */
114  xpathObj = xmlXPathEvalExpression((xmlChar*)expression, xpathCtx);
115  if(xpathObj == NULL) {
116  fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", expression);
117  xmlXPathFreeContext(xpathCtx);
118  return NULL;
119  }
120 
121  xmlXPathFreeContext(xpathCtx);
122  /* Cleanup of XPath data */
123  // xmlXPathFreeObject(xpathObj);
124  return xpathObj;
125 }
126 
127 xmlXPathObject *osxml_get_unknown_nodes(xmlDoc *doc)
128 {
129  return osxml_get_nodeset(doc, "/*/*[@Type='Unknown']");
130 }
131 
132 void osxml_map_unknown_param(xmlNode *node, const char *paramname, const char *newname)
133 {
134  xmlNode *cur = node->xmlChildrenNode;
135  while (cur) {
136  if (xmlStrcmp(cur->name, (const xmlChar *)"UnknownParam"))
137  goto next;
138 
139  char *name = osxml_find_node(cur, "ParamName");
140  char *content = osxml_find_node(cur, "Content");
141  if (!strcmp(name, paramname)) {
142  osxml_node_add(node, newname, content);
143  osxml_node_remove_unknown_mark(node);
144 
145  xmlUnlinkNode(cur);
146  xmlFreeNode(cur);
147  g_free(name);
148  g_free(content);
149  return;
150  }
151 
152  g_free(name);
153  g_free(content);
154 
155  next:;
156  cur = cur->next;
157  }
158 }
159 
160 osync_bool osxml_has_property_full(xmlNode *parent, const char *name, const char *data)
161 {
162  if (osxml_has_property(parent, name))
163  return (strcmp((char*)xmlGetProp(parent, (xmlChar*)name), data) == 0);
164  return FALSE;
165 }
166 
167 char *osxml_find_property(xmlNode *parent, const char *name)
168 {
169  return (char*)xmlGetProp(parent, (xmlChar*)name);
170 }
171 
172 osync_bool osxml_has_property(xmlNode *parent, const char *name)
173 {
174  return (xmlHasProp(parent, (xmlChar*)name) != NULL);
175 }
176 
177 xmlChar *osxml_write_to_string(xmlDoc *doc)
178 {
179  xmlKeepBlanksDefault(0);
180  xmlChar *temp = NULL;
181  int size = 0;
182  xmlDocDumpFormatMemoryEnc(doc, &temp, &size, NULL, 1);
183  return temp;
184 }
185 
186 osync_bool osxml_copy(const char *input, int inpsize, char **output, int *outpsize)
187 {
188  xmlDoc *doc = (xmlDoc *)(input);
189  xmlDoc *newdoc = xmlCopyDoc(doc, TRUE);
190  *output = (char *)newdoc;
191  *outpsize = sizeof(newdoc);
192  return TRUE;
193 }
194 
195 osync_bool osxml_marshall(const char *input, int inpsize, char **output, int *outpsize, OSyncError **error)
196 {
197  xmlDoc *doc = (xmlDoc*)input;
198  xmlChar *result;
199  int size;
200  xmlDocDumpMemory(doc, &result, &size);
201  *output = (char*)result;
202  *outpsize = size;
203  return TRUE;
204 }
205 
206 osync_bool osxml_demarshall(const char *input, int inpsize, char **output, int *outpsize, OSyncError **error)
207 {
208  xmlDoc *doc = xmlParseMemory(input, inpsize);
209  if (!doc) {
210  osync_error_set(error, OSYNC_ERROR_GENERIC, "Invalid XML data received");
211  goto error;
212  }
213 
214  *output = (char*)doc;
215  *outpsize = sizeof(*doc);
216  return TRUE;
217 
218 error:
219  return FALSE;
220 }
221 
222 
Represent an error.
void osync_error_set(OSyncError **error, OSyncErrorType type, const char *format,...)
Sets the error.