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