1 /*******************************************************************************
2 *
3 * Copyright (c) 2000-2003 Intel Corporation
4 * All rights reserved.
5 * Copyright (c) 2012 France Telecom All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 * - Neither name of Intel Corporation nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
27 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 ******************************************************************************/
32
33
34 /*!
35 * \file
36 */
37
38
39 #include "ixmldebug.h"
40 #include "ixmlparser.h"
41
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46
47
ixmlDocument_init(IXML_Document * doc)48 void ixmlDocument_init(IXML_Document *doc)
49 {
50 memset(doc, 0, sizeof(IXML_Document));
51 }
52
53
ixmlDocument_free(IXML_Document * doc)54 void ixmlDocument_free(IXML_Document *doc)
55 {
56 if (doc != NULL) {
57 ixmlNode_free((IXML_Node *)doc);
58 }
59 }
60
61
62 /*!
63 * When this function is called first time, nodeptr is the root of the subtree,
64 * so it is not necessay to do two steps recursion.
65 *
66 * Internal function called by ixmlDocument_importNode
67 */
ixmlDocument_setOwnerDocument(IXML_Document * doc,IXML_Node * nodeptr)68 static void ixmlDocument_setOwnerDocument(
69 /*! [in] The document node. */
70 IXML_Document *doc,
71 /*! [in] \todo documentation. */
72 IXML_Node *nodeptr)
73 {
74 if (nodeptr != NULL) {
75 nodeptr->ownerDocument = doc;
76 ixmlDocument_setOwnerDocument(
77 doc, ixmlNode_getFirstChild(nodeptr));
78 ixmlDocument_setOwnerDocument(
79 doc, ixmlNode_getNextSibling(nodeptr));
80 }
81 }
82
83
ixmlDocument_importNode(IXML_Document * doc,IXML_Node * importNode,int deep,IXML_Node ** rtNode)84 int ixmlDocument_importNode(
85 IXML_Document *doc,
86 IXML_Node *importNode,
87 int deep,
88 IXML_Node **rtNode)
89 {
90 unsigned short nodeType;
91 IXML_Node *newNode;
92
93 *rtNode = NULL;
94
95 if (doc == NULL || importNode == NULL) {
96 return IXML_INVALID_PARAMETER;
97 }
98
99 nodeType = ixmlNode_getNodeType(importNode);
100 if (nodeType == eDOCUMENT_NODE) {
101 return IXML_NOT_SUPPORTED_ERR;
102 }
103
104 newNode = ixmlNode_cloneNode(importNode, deep);
105 if (newNode == NULL) {
106 return IXML_FAILED;
107 }
108
109 ixmlDocument_setOwnerDocument(doc, newNode);
110 *rtNode = newNode;
111
112 return IXML_SUCCESS;
113 }
114
115
ixmlDocument_createElementEx(IXML_Document * doc,const DOMString tagName,IXML_Element ** rtElement)116 int ixmlDocument_createElementEx(
117 IXML_Document *doc,
118 const DOMString tagName,
119 IXML_Element **rtElement)
120 {
121 int errCode = IXML_SUCCESS;
122 IXML_Element *newElement = NULL;
123
124 if (doc == NULL || tagName == NULL) {
125 errCode = IXML_INVALID_PARAMETER;
126 goto ErrorHandler;
127 }
128
129 newElement = (IXML_Element *) malloc(sizeof(IXML_Element));
130 if (newElement == NULL) {
131 errCode = IXML_INSUFFICIENT_MEMORY;
132 goto ErrorHandler;
133 }
134
135 ixmlElement_init(newElement);
136 newElement->tagName = strdup(tagName);
137 if (newElement->tagName == NULL) {
138 ixmlElement_free(newElement);
139 newElement = NULL;
140 errCode = IXML_INSUFFICIENT_MEMORY;
141 goto ErrorHandler;
142 }
143 /* set the node fields */
144 newElement->n.nodeType = eELEMENT_NODE;
145 newElement->n.nodeName = strdup(tagName);
146 if (newElement->n.nodeName == NULL) {
147 free(newElement->tagName);
148 ixmlElement_free(newElement);
149 newElement = NULL;
150 errCode = IXML_INSUFFICIENT_MEMORY;
151 goto ErrorHandler;
152 }
153
154 newElement->n.ownerDocument = doc;
155
156 ErrorHandler:
157 *rtElement = newElement;
158
159 return errCode;
160 }
161
162
ixmlDocument_createElement(IXML_Document * doc,const DOMString tagName)163 IXML_Element *ixmlDocument_createElement(
164 IXML_Document *doc,
165 const DOMString tagName)
166 {
167 IXML_Element *newElement = NULL;
168 int ret = IXML_SUCCESS;
169
170 ret = ixmlDocument_createElementEx(doc, tagName, &newElement);
171 if (ret != IXML_SUCCESS) {
172 IxmlPrintf(__FILE__, __LINE__, "ixmlDocument_createElement",
173 "Error %d\n", ret);
174 return NULL;
175 }
176 return newElement;
177 }
178
179
ixmlDocument_createDocumentEx(IXML_Document ** rtDoc)180 int ixmlDocument_createDocumentEx(IXML_Document **rtDoc)
181 {
182 IXML_Document *doc;
183 int errCode = IXML_SUCCESS;
184
185 doc = NULL;
186 doc = (IXML_Document *)malloc(sizeof (IXML_Document));
187 if (doc == NULL) {
188 errCode = IXML_INSUFFICIENT_MEMORY;
189 goto ErrorHandler;
190 }
191
192 ixmlDocument_init(doc);
193
194 doc->n.nodeName = strdup((const char*)DOCUMENTNODENAME);
195 if (doc->n.nodeName == NULL) {
196 ixmlDocument_free(doc);
197 doc = NULL;
198 errCode = IXML_INSUFFICIENT_MEMORY;
199 goto ErrorHandler;
200 }
201
202 doc->n.nodeType = eDOCUMENT_NODE;
203 doc->n.ownerDocument = doc;
204
205 ErrorHandler:
206 *rtDoc = doc;
207 return errCode;
208 }
209
210
ixmlDocument_createDocument()211 IXML_Document *ixmlDocument_createDocument()
212 {
213 IXML_Document *doc = NULL;
214
215 ixmlDocument_createDocumentEx(&doc);
216
217 return doc;
218 }
219
220
ixmlDocument_createTextNodeEx(IXML_Document * doc,const DOMString data,IXML_Node ** textNode)221 int ixmlDocument_createTextNodeEx(
222 IXML_Document *doc,
223 const DOMString data,
224 IXML_Node **textNode)
225 {
226 IXML_Node *returnNode;
227 int rc = IXML_SUCCESS;
228
229 returnNode = NULL;
230 if (doc == NULL || data == NULL) {
231 rc = IXML_INVALID_PARAMETER;
232 goto ErrorHandler;
233 }
234
235 returnNode = (IXML_Node *)malloc(sizeof (IXML_Node));
236 if (returnNode == NULL) {
237 rc = IXML_INSUFFICIENT_MEMORY;
238 goto ErrorHandler;
239 }
240 /* initialize the node */
241 ixmlNode_init(returnNode);
242
243 returnNode->nodeName = strdup((const char*)TEXTNODENAME);
244 if (returnNode->nodeName == NULL) {
245 ixmlNode_free(returnNode);
246 returnNode = NULL;
247 rc = IXML_INSUFFICIENT_MEMORY;
248 goto ErrorHandler;
249 }
250 /* add in node value */
251 if (data != NULL) {
252 returnNode->nodeValue = strdup(data);
253 if (returnNode->nodeValue == NULL) {
254 ixmlNode_free(returnNode);
255 returnNode = NULL;
256 rc = IXML_INSUFFICIENT_MEMORY;
257 goto ErrorHandler;
258 }
259 }
260
261 returnNode->nodeType = eTEXT_NODE;
262 returnNode->ownerDocument = doc;
263
264 ErrorHandler:
265 *textNode = returnNode;
266 return rc;
267 }
268
269
ixmlDocument_createTextNode(IXML_Document * doc,const DOMString data)270 IXML_Node *ixmlDocument_createTextNode(
271 IXML_Document *doc,
272 const DOMString data)
273 {
274 IXML_Node *returnNode = NULL;
275
276 ixmlDocument_createTextNodeEx(doc, data, &returnNode);
277
278 return returnNode;
279 }
280
281
ixmlDocument_createAttributeEx(IXML_Document * doc,const DOMString name,IXML_Attr ** rtAttr)282 int ixmlDocument_createAttributeEx(
283 IXML_Document *doc,
284 const DOMString name,
285 IXML_Attr **rtAttr)
286 {
287 IXML_Attr *attrNode = NULL;
288 int errCode = IXML_SUCCESS;
289
290 attrNode = (IXML_Attr *)malloc(sizeof (IXML_Attr));
291 if (attrNode == NULL) {
292 errCode = IXML_INSUFFICIENT_MEMORY;
293 goto ErrorHandler;
294 }
295
296 if (doc == NULL || name == NULL) {
297 ixmlAttr_free(attrNode);
298 attrNode = NULL;
299 errCode = IXML_INVALID_PARAMETER;
300 goto ErrorHandler;
301 }
302
303 ixmlAttr_init(attrNode);
304 attrNode->n.nodeType = eATTRIBUTE_NODE;
305
306 /* set the node fields */
307 attrNode->n.nodeName = strdup(name);
308 if (attrNode->n.nodeName == NULL) {
309 ixmlAttr_free(attrNode);
310 attrNode = NULL;
311 errCode = IXML_INSUFFICIENT_MEMORY;
312 goto ErrorHandler;
313 }
314
315 attrNode->n.ownerDocument = doc;
316
317 ErrorHandler:
318 *rtAttr = attrNode;
319 return errCode;
320 }
321
322
ixmlDocument_createAttribute(IXML_Document * doc,const DOMString name)323 IXML_Attr *ixmlDocument_createAttribute(
324 IXML_Document *doc,
325 const DOMString name)
326 {
327 IXML_Attr *attrNode = NULL;
328
329 if(ixmlDocument_createAttributeEx(doc, name, &attrNode) != IXML_SUCCESS)
330 return NULL;
331
332 return attrNode;
333 }
334
335
ixmlDocument_createAttributeNSEx(IXML_Document * doc,const DOMString namespaceURI,const DOMString qualifiedName,IXML_Attr ** rtAttr)336 int ixmlDocument_createAttributeNSEx(
337 IXML_Document *doc,
338 const DOMString namespaceURI,
339 const DOMString qualifiedName,
340 IXML_Attr **rtAttr )
341 {
342 IXML_Attr *attrNode = NULL;
343 int errCode = IXML_SUCCESS;
344
345 if (doc == NULL || namespaceURI == NULL || qualifiedName == NULL) {
346 errCode = IXML_INVALID_PARAMETER;
347 goto ErrorHandler;
348 }
349
350 errCode =
351 ixmlDocument_createAttributeEx(doc, qualifiedName, &attrNode);
352 if (errCode != IXML_SUCCESS) {
353 goto ErrorHandler;
354 }
355 /* set the namespaceURI field */
356 attrNode->n.namespaceURI = strdup(namespaceURI);
357 if (attrNode->n.namespaceURI == NULL) {
358 ixmlAttr_free(attrNode);
359 attrNode = NULL;
360 errCode = IXML_INSUFFICIENT_MEMORY;
361 goto ErrorHandler;
362 }
363 /* set the localName and prefix */
364 errCode =
365 ixmlNode_setNodeName((IXML_Node *)attrNode, qualifiedName);
366 if (errCode != IXML_SUCCESS) {
367 ixmlAttr_free(attrNode);
368 attrNode = NULL;
369 goto ErrorHandler;
370 }
371
372 ErrorHandler:
373 *rtAttr = attrNode;
374 return errCode;
375 }
376
377
ixmlDocument_createAttributeNS(IXML_Document * doc,const DOMString namespaceURI,const DOMString qualifiedName)378 IXML_Attr *ixmlDocument_createAttributeNS(
379 IXML_Document *doc,
380 const DOMString namespaceURI,
381 const DOMString qualifiedName)
382 {
383 IXML_Attr *attrNode = NULL;
384
385 ixmlDocument_createAttributeNSEx(
386 doc, namespaceURI, qualifiedName, &attrNode);
387
388 return attrNode;
389 }
390
391
ixmlDocument_createCDATASectionEx(IXML_Document * doc,const DOMString data,IXML_CDATASection ** rtCD)392 int ixmlDocument_createCDATASectionEx(
393 IXML_Document *doc,
394 const DOMString data,
395 IXML_CDATASection **rtCD)
396 {
397 int errCode = IXML_SUCCESS;
398 IXML_CDATASection *cDSectionNode = NULL;
399
400 if(doc == NULL || data == NULL) {
401 errCode = IXML_INVALID_PARAMETER;
402 goto ErrorHandler;
403 }
404
405 cDSectionNode = (IXML_CDATASection *)malloc(sizeof (IXML_CDATASection));
406 if (cDSectionNode == NULL) {
407 errCode = IXML_INSUFFICIENT_MEMORY;
408 goto ErrorHandler;
409 }
410
411 ixmlCDATASection_init(cDSectionNode);
412 cDSectionNode->n.nodeType = eCDATA_SECTION_NODE;
413 cDSectionNode->n.nodeName = strdup((const char*)CDATANODENAME);
414 if (cDSectionNode->n.nodeName == NULL) {
415 ixmlCDATASection_free(cDSectionNode);
416 cDSectionNode = NULL;
417 errCode = IXML_INSUFFICIENT_MEMORY;
418 goto ErrorHandler;
419 }
420
421 cDSectionNode->n.nodeValue = strdup(data);
422 if (cDSectionNode->n.nodeValue == NULL) {
423 ixmlCDATASection_free( cDSectionNode );
424 cDSectionNode = NULL;
425 errCode = IXML_INSUFFICIENT_MEMORY;
426 goto ErrorHandler;
427 }
428
429 cDSectionNode->n.ownerDocument = doc;
430
431 ErrorHandler:
432 *rtCD = cDSectionNode;
433 return errCode;
434 }
435
436
ixmlDocument_createCDATASection(IXML_Document * doc,const DOMString data)437 IXML_CDATASection *ixmlDocument_createCDATASection(
438 IXML_Document *doc,
439 const DOMString data)
440 {
441 IXML_CDATASection *cDSectionNode = NULL;
442
443 ixmlDocument_createCDATASectionEx(doc, data, &cDSectionNode);
444
445 return cDSectionNode;
446 }
447
448
ixmlDocument_createElementNSEx(IXML_Document * doc,const DOMString namespaceURI,const DOMString qualifiedName,IXML_Element ** rtElement)449 int ixmlDocument_createElementNSEx(
450 IXML_Document *doc,
451 const DOMString namespaceURI,
452 const DOMString qualifiedName,
453 IXML_Element **rtElement)
454 {
455 IXML_Element *newElement = NULL;
456 int ret = IXML_SUCCESS;
457 int line = 0;
458
459 if (doc == NULL || namespaceURI == NULL || qualifiedName == NULL) {
460 line = __LINE__;
461 ret = IXML_INVALID_PARAMETER;
462 goto ErrorHandler;
463 }
464
465 ret = ixmlDocument_createElementEx(doc, qualifiedName, &newElement);
466 if (ret != IXML_SUCCESS) {
467 line = __LINE__;
468 goto ErrorHandler;
469 }
470 /* set the namespaceURI field */
471 newElement->n.namespaceURI = strdup(namespaceURI);
472 if (newElement->n.namespaceURI == NULL) {
473 line = __LINE__;
474 ixmlElement_free(newElement);
475 newElement = NULL;
476 ret = IXML_INSUFFICIENT_MEMORY;
477 goto ErrorHandler;
478 }
479 /* set the localName and prefix */
480 ret = ixmlNode_setNodeName((IXML_Node *)newElement, qualifiedName);
481 if (ret != IXML_SUCCESS) {
482 line = __LINE__;
483 ixmlElement_free(newElement);
484 newElement = NULL;
485 ret = IXML_INSUFFICIENT_MEMORY;
486 goto ErrorHandler;
487 }
488
489 newElement->n.nodeValue = NULL;
490
491 ErrorHandler:
492 *rtElement = newElement;
493 if (ret != IXML_SUCCESS) {
494 IxmlPrintf(__FILE__, line, "ixmlDocument_createElementNSEx", "Error %d\n", ret);
495 }
496
497 return ret;
498 }
499
500
ixmlDocument_createElementNS(IXML_Document * doc,const DOMString namespaceURI,const DOMString qualifiedName)501 IXML_Element *ixmlDocument_createElementNS(
502 IXML_Document *doc,
503 const DOMString namespaceURI,
504 const DOMString qualifiedName)
505 {
506 IXML_Element *newElement = NULL;
507
508 ixmlDocument_createElementNSEx(doc, namespaceURI, qualifiedName, &newElement);
509
510 return newElement;
511 }
512
513
ixmlDocument_getElementsByTagName(IXML_Document * doc,const DOMString tagName)514 IXML_NodeList *ixmlDocument_getElementsByTagName(
515 IXML_Document *doc,
516 const DOMString tagName)
517 {
518 IXML_NodeList *returnNodeList = NULL;
519
520 if (doc == NULL || tagName == NULL) {
521 return NULL;
522 }
523
524 ixmlNode_getElementsByTagName((IXML_Node *)doc, tagName, &returnNodeList);
525
526 return returnNodeList;
527 }
528
529
ixmlDocument_getElementsByTagNameNS(IXML_Document * doc,const DOMString namespaceURI,const DOMString localName)530 IXML_NodeList *ixmlDocument_getElementsByTagNameNS(
531 IXML_Document *doc,
532 const DOMString namespaceURI,
533 const DOMString localName)
534 {
535 IXML_NodeList *returnNodeList = NULL;
536
537 if (doc == NULL || namespaceURI == NULL || localName == NULL) {
538 return NULL;
539 }
540
541 ixmlNode_getElementsByTagNameNS(
542 (IXML_Node *)doc, namespaceURI, localName, &returnNodeList);
543
544 return returnNodeList;
545 }
546
547
ixmlDocument_getElementById(IXML_Document * doc,const DOMString tagName)548 IXML_Element *ixmlDocument_getElementById(
549 IXML_Document *doc,
550 const DOMString tagName)
551 {
552 IXML_Element *rtElement = NULL;
553 IXML_Node *nodeptr = (IXML_Node *)doc;
554 const char *name;
555
556 if (nodeptr == NULL || tagName == NULL) {
557 return rtElement;
558 }
559
560 if (ixmlNode_getNodeType(nodeptr) == eELEMENT_NODE) {
561 name = ixmlNode_getNodeName(nodeptr);
562 if (name == NULL) {
563 return rtElement;
564 }
565
566 if (strcmp(tagName, name) == 0) {
567 rtElement = (IXML_Element *)nodeptr;
568 return rtElement;
569 } else {
570 rtElement = ixmlDocument_getElementById(
571 (IXML_Document *)ixmlNode_getFirstChild(nodeptr),
572 tagName );
573 if (rtElement == NULL) {
574 rtElement = ixmlDocument_getElementById(
575 (IXML_Document *)ixmlNode_getNextSibling(nodeptr),
576 tagName);
577 }
578 }
579 } else {
580 rtElement = ixmlDocument_getElementById(
581 (IXML_Document *)ixmlNode_getFirstChild(nodeptr),
582 tagName);
583 if (rtElement == NULL) {
584 rtElement = ixmlDocument_getElementById(
585 (IXML_Document *)ixmlNode_getNextSibling(nodeptr),
586 tagName);
587 }
588 }
589
590 return rtElement;
591 }
592
593