2 * XML Security Library (http://www.aleksey.com/xmlsec).
4 * Common XML Doc utility functions
6 * This is free software; see Copyright file in the source
7 * distribution for preciese wording.
9 * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
18 #include <libxml/tree.h>
19 #include <libxml/valid.h>
20 #include <libxml/xpath.h>
21 #include <libxml/xpathInternals.h>
23 #include <xmlsec/xmlsec.h>
24 #include <xmlsec/xmltree.h>
25 #include <xmlsec/parser.h>
26 #include <xmlsec/private.h>
27 #include <xmlsec/base64.h>
28 #include <xmlsec/errors.h>
32 * @parent: the pointer to XML node.
34 * @ns: the namespace href (may be NULL).
36 * Searches a direct child of the @parent node having given name and
39 * Returns: the pointer to the found node or NULL if an error occurs or
43 xmlSecFindChild(const xmlNodePtr parent, const xmlChar *name, const xmlChar *ns) {
46 xmlSecAssert2(parent != NULL, NULL);
47 xmlSecAssert2(name != NULL, NULL);
49 cur = parent->children;
51 if(cur->type == XML_ELEMENT_NODE) {
52 if(xmlSecCheckNodeName(cur, name, ns)) {
63 * @cur: the pointer to an XML node.
65 * @ns: the namespace href (may be NULL).
67 * Searches the ancestors axis of the @cur node for a node having given name
70 * Returns: the pointer to the found node or NULL if an error occurs or
74 xmlSecFindParent(const xmlNodePtr cur, const xmlChar *name, const xmlChar *ns) {
75 xmlSecAssert2(cur != NULL, NULL);
76 xmlSecAssert2(name != NULL, NULL);
78 if(xmlSecCheckNodeName(cur, name, ns)) {
80 } else if(cur->parent != NULL) {
81 return(xmlSecFindParent(cur->parent, name, ns));
88 * @parent: the pointer to XML node.
90 * @ns: the namespace href (may be NULL).
92 * Searches all children of the @parent node having given name and
95 * Returns: the pointer to the found node or NULL if an error occurs or
99 xmlSecFindNode(const xmlNodePtr parent, const xmlChar *name, const xmlChar *ns) {
103 xmlSecAssert2(name != NULL, NULL);
107 if((cur->type == XML_ELEMENT_NODE) && xmlSecCheckNodeName(cur, name, ns)) {
110 if(cur->children != NULL) {
111 ret = xmlSecFindNode(cur->children, name, ns);
122 * xmlSecGetNodeNsHref:
123 * @cur: the pointer to node.
125 * Get's node's namespace href.
127 * Returns: node's namespace href.
130 xmlSecGetNodeNsHref(const xmlNodePtr cur) {
133 xmlSecAssert2(cur != NULL, NULL);
135 /* do we have a namespace in the node? */
136 if(cur->ns != NULL) {
137 return(cur->ns->href);
140 /* search for default namespace */
141 ns = xmlSearchNs(cur->doc, cur, NULL);
150 * xmlSecCheckNodeName:
151 * @cur: the pointer to an XML node.
153 * @ns: the namespace href.
155 * Checks that the node has a given name and a given namespace href.
157 * Returns: 1 if the node matches or 0 otherwise.
160 xmlSecCheckNodeName(const xmlNodePtr cur, const xmlChar *name, const xmlChar *ns) {
161 xmlSecAssert2(cur != NULL, 0);
163 return(xmlStrEqual(cur->name, name) &&
164 xmlStrEqual(xmlSecGetNodeNsHref(cur), ns));
169 * @parent: the pointer to an XML node.
170 * @name: the new node name.
171 * @ns: the new node namespace.
173 * Adds a child to the node @parent with given @name and namespace @ns.
175 * Returns: pointer to the new node or NULL if an error occurs.
178 xmlSecAddChild(xmlNodePtr parent, const xmlChar *name, const xmlChar *ns) {
182 xmlSecAssert2(parent != NULL, NULL);
183 xmlSecAssert2(name != NULL, NULL);
185 if(parent->children == NULL) {
186 /* TODO: add indents */
187 text = xmlNewText(xmlSecStringCR);
189 xmlSecError(XMLSEC_ERRORS_HERE,
192 XMLSEC_ERRORS_R_XML_FAILED,
193 XMLSEC_ERRORS_NO_MESSAGE);
196 xmlAddChild(parent, text);
199 cur = xmlNewChild(parent, NULL, name, NULL);
201 xmlSecError(XMLSEC_ERRORS_HERE,
204 XMLSEC_ERRORS_R_XML_FAILED,
205 XMLSEC_ERRORS_NO_MESSAGE);
209 /* namespaces support */
213 /* find namespace by href and check that its prefix is not overwritten */
214 nsPtr = xmlSearchNsByHref(cur->doc, cur, ns);
215 if((nsPtr == NULL) || (xmlSearchNs(cur->doc, cur, nsPtr->prefix) != nsPtr)) {
216 nsPtr = xmlNewNs(cur, ns, NULL);
218 xmlSetNs(cur, nsPtr);
221 /* TODO: add indents */
222 text = xmlNewText(xmlSecStringCR);
224 xmlSecError(XMLSEC_ERRORS_HERE,
227 XMLSEC_ERRORS_R_XML_FAILED,
228 XMLSEC_ERRORS_NO_MESSAGE);
231 xmlAddChild(parent, text);
237 * xmlSecAddChildNode:
238 * @parent: the pointer to an XML node.
239 * @child: the new node.
241 * Adds @child node to the @parent node.
243 * Returns: pointer to the new node or NULL if an error occurs.
246 xmlSecAddChildNode(xmlNodePtr parent, xmlNodePtr child) {
249 xmlSecAssert2(parent != NULL, NULL);
250 xmlSecAssert2(child != NULL, NULL);
252 if(parent->children == NULL) {
253 /* TODO: add indents */
254 text = xmlNewText(xmlSecStringCR);
256 xmlSecError(XMLSEC_ERRORS_HERE,
259 XMLSEC_ERRORS_R_XML_FAILED,
260 XMLSEC_ERRORS_NO_MESSAGE);
263 xmlAddChild(parent, text);
266 xmlAddChild(parent, child);
268 /* TODO: add indents */
269 text = xmlNewText(xmlSecStringCR);
271 xmlSecError(XMLSEC_ERRORS_HERE,
274 XMLSEC_ERRORS_R_XML_FAILED,
275 XMLSEC_ERRORS_NO_MESSAGE);
278 xmlAddChild(parent, text);
284 * xmlSecAddNextSibling
285 * @node: the pointer to an XML node.
286 * @name: the new node name.
287 * @ns: the new node namespace.
289 * Adds next sibling to the node @node with given @name and namespace @ns.
291 * Returns: pointer to the new node or NULL if an error occurs.
294 xmlSecAddNextSibling(xmlNodePtr node, const xmlChar *name, const xmlChar *ns) {
298 xmlSecAssert2(node != NULL, NULL);
299 xmlSecAssert2(name != NULL, NULL);
301 cur = xmlNewNode(NULL, name);
303 xmlSecError(XMLSEC_ERRORS_HERE,
306 XMLSEC_ERRORS_R_XML_FAILED,
307 XMLSEC_ERRORS_NO_MESSAGE);
310 xmlAddNextSibling(node, cur);
312 /* namespaces support */
316 /* find namespace by href and check that its prefix is not overwritten */
317 nsPtr = xmlSearchNsByHref(cur->doc, cur, ns);
318 if((nsPtr == NULL) || (xmlSearchNs(cur->doc, cur, nsPtr->prefix) != nsPtr)) {
319 nsPtr = xmlNewNs(cur, ns, NULL);
321 xmlSetNs(cur, nsPtr);
324 /* TODO: add indents */
325 text = xmlNewText(xmlSecStringCR);
327 xmlSecError(XMLSEC_ERRORS_HERE,
330 XMLSEC_ERRORS_R_XML_FAILED,
331 XMLSEC_ERRORS_NO_MESSAGE);
334 xmlAddNextSibling(node, text);
340 * xmlSecAddPrevSibling
341 * @node: the pointer to an XML node.
342 * @name: the new node name.
343 * @ns: the new node namespace.
345 * Adds prev sibling to the node @node with given @name and namespace @ns.
347 * Returns: pointer to the new node or NULL if an error occurs.
350 xmlSecAddPrevSibling(xmlNodePtr node, const xmlChar *name, const xmlChar *ns) {
354 xmlSecAssert2(node != NULL, NULL);
355 xmlSecAssert2(name != NULL, NULL);
357 cur = xmlNewNode(NULL, name);
359 xmlSecError(XMLSEC_ERRORS_HERE,
362 XMLSEC_ERRORS_R_XML_FAILED,
363 XMLSEC_ERRORS_NO_MESSAGE);
366 xmlAddPrevSibling(node, cur);
368 /* namespaces support */
372 /* find namespace by href and check that its prefix is not overwritten */
373 nsPtr = xmlSearchNsByHref(cur->doc, cur, ns);
374 if((nsPtr == NULL) || (xmlSearchNs(cur->doc, cur, nsPtr->prefix) != nsPtr)) {
375 nsPtr = xmlNewNs(cur, ns, NULL);
377 xmlSetNs(cur, nsPtr);
380 /* TODO: add indents */
381 text = xmlNewText(xmlSecStringCR);
383 xmlSecError(XMLSEC_ERRORS_HERE,
386 XMLSEC_ERRORS_R_XML_FAILED,
387 XMLSEC_ERRORS_NO_MESSAGE);
390 xmlAddPrevSibling(node, text);
396 * xmlSecGetNextElementNode:
397 * @cur: the pointer to an XML node.
399 * Seraches for the next element node.
401 * Returns: the pointer to next element node or NULL if it is not found.
404 xmlSecGetNextElementNode(xmlNodePtr cur) {
406 while((cur != NULL) && (cur->type != XML_ELEMENT_NODE)) {
414 * @node: the current node.
415 * @newNode: the new node.
417 * Swaps the @node and @newNode in the XML tree.
419 * Returns: 0 on success or a negative value if an error occurs.
422 xmlSecReplaceNode(xmlNodePtr node, xmlNodePtr newNode) {
423 return xmlSecReplaceNodeAndReturn(node, newNode, NULL);
427 * xmlSecReplaceNodeAndReturn:
428 * @node: the current node.
429 * @newNode: the new node.
430 * @replaced: the replaced node, or release it if NULL is given
432 * Swaps the @node and @newNode in the XML tree.
434 * Returns: 0 on success or a negative value if an error occurs.
437 xmlSecReplaceNodeAndReturn(xmlNodePtr node, xmlNodePtr newNode, xmlNodePtr* replaced) {
441 xmlSecAssert2(node != NULL, -1);
442 xmlSecAssert2(newNode != NULL, -1);
444 /* fix documents children if necessary first */
445 if((node->doc != NULL) && (node->doc->children == node)) {
446 node->doc->children = node->next;
449 if((newNode->doc != NULL) && (newNode->doc->children == newNode)) {
450 newNode->doc->children = newNode->next;
453 oldNode = xmlReplaceNode(node, newNode);
454 if(oldNode == NULL) {
455 xmlSecError(XMLSEC_ERRORS_HERE,
458 XMLSEC_ERRORS_R_XML_FAILED,
459 XMLSEC_ERRORS_NO_MESSAGE);
463 if(restoreRoot != 0) {
464 xmlDocSetRootElement(oldNode->doc, newNode);
467 /* return the old node if requested */
468 if(replaced != NULL) {
469 (*replaced) = oldNode;
471 xmlFreeNode(oldNode);
478 * xmlSecReplaceContent
479 * @node: the current node.
480 * @newNode: the new node.
482 * Swaps the content of @node and @newNode.
484 * Returns: 0 on success or a negative value if an error occurs.
487 xmlSecReplaceContent(xmlNodePtr node, xmlNodePtr newNode) {
488 return xmlSecReplaceContentAndReturn(node, newNode, NULL);
492 * xmlSecReplaceContentAndReturn
493 * @node: the current node.
494 * @newNode: the new node.
495 * @replaced: the replaced nodes, or release them if NULL is given
497 * Swaps the content of @node and @newNode.
499 * Returns: 0 on success or a negative value if an error occurs.
502 xmlSecReplaceContentAndReturn(xmlNodePtr node, xmlNodePtr newNode, xmlNodePtr *replaced) {
503 xmlSecAssert2(node != NULL, -1);
504 xmlSecAssert2(newNode != NULL, -1);
506 xmlUnlinkNode(newNode);
507 xmlSetTreeDoc(newNode, node->doc);
509 /* return the old nodes if requested */
510 if(replaced != NULL) {
511 xmlNodePtr cur, next, tail;
513 (*replaced) = tail = NULL;
514 for(cur = node->children; (cur != NULL); cur = next) {
516 if((*replaced) != NULL) {
517 /* n is unlinked in this function */
518 xmlAddNextSibling(tail, cur);
521 /* this is the first node, (*replaced) is the head */
523 (*replaced) = tail = cur;
527 /* just delete the content */
528 xmlNodeSetContent(node, NULL);
531 xmlAddChild(node, newNode);
532 xmlSetTreeDoc(newNode, node->doc);
538 * xmlSecReplaceNodeBuffer:
539 * @node: the current node.
540 * @buffer: the XML data.
541 * @size: the XML data size.
543 * Swaps the @node and the parsed XML data from the @buffer in the XML tree.
545 * Returns: 0 on success or a negative value if an error occurs.
548 xmlSecReplaceNodeBuffer(xmlNodePtr node, const xmlSecByte *buffer, xmlSecSize size) {
549 return xmlSecReplaceNodeBufferAndReturn(node, buffer, size, NULL);
553 * xmlSecReplaceNodeBufferAndReturn:
554 * @node: the current node.
555 * @buffer: the XML data.
556 * @size: the XML data size.
557 * @replaced: the replaced nodes, or release them if NULL is given
559 * Swaps the @node and the parsed XML data from the @buffer in the XML tree.
561 * Returns: 0 on success or a negative value if an error occurs.
564 xmlSecReplaceNodeBufferAndReturn(xmlNodePtr node, const xmlSecByte *buffer, xmlSecSize size, xmlNodePtr *replaced) {
565 xmlNodePtr results = NULL;
566 xmlNodePtr next = NULL;
568 xmlSecAssert2(node != NULL, -1);
569 xmlSecAssert2(node->parent != NULL, -1);
571 /* parse buffer in the context of node's parent */
572 if(xmlParseInNodeContext(node->parent, (const char*)buffer, size, XML_PARSE_NODICT, &results) != XML_ERR_OK) {
573 xmlSecError(XMLSEC_ERRORS_HERE,
575 "xmlParseInNodeContext",
576 XMLSEC_ERRORS_R_XML_FAILED,
577 "Failed to parse content");
582 while (results != NULL) {
583 next = results->next;
584 xmlAddPrevSibling(node, results);
588 /* remove old node */
591 /* return the old node if requested */
592 if(replaced != NULL) {
602 * xmlSecNodeEncodeAndSetContent:
603 * @node: the pointer to an XML node.
604 * @buffer: the pointer to the node content.
606 * Encodes "special" characters in the @buffer and sets the result
607 * as the node content.
609 * Returns: 0 on success or a negative value if an error occurs.
612 xmlSecNodeEncodeAndSetContent(xmlNodePtr node, const xmlChar * buffer) {
613 xmlSecAssert2(node != NULL, -1);
614 xmlSecAssert2(node->doc != NULL, -1);
619 tmp = xmlEncodeSpecialChars(node->doc, buffer);
621 xmlSecError(XMLSEC_ERRORS_HERE,
623 "xmlEncodeSpecialChars",
624 XMLSEC_ERRORS_R_XML_FAILED,
625 "Failed to encode special characters");
629 xmlNodeSetContent(node, tmp);
632 xmlNodeSetContent(node, NULL);
640 * @doc: the pointer to an XML document.
641 * @cur: the pointer to an XML node.
642 * @ids: the pointer to a NULL terminated list of ID attributes.
644 * Walks thru all children of the @cur node and adds all attributes
645 * from the @ids list to the @doc document IDs attributes hash.
648 xmlSecAddIDs(xmlDocPtr doc, xmlNodePtr cur, const xmlChar** ids) {
649 xmlNodePtr children = NULL;
651 xmlSecAssert(doc != NULL);
652 xmlSecAssert(ids != NULL);
654 if((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
660 for(attr = cur->properties; attr != NULL; attr = attr->next) {
661 for(i = 0; ids[i] != NULL; ++i) {
662 if(xmlStrEqual(attr->name, ids[i])) {
663 name = xmlNodeListGetString(doc, attr->children, 1);
665 tmp = xmlGetID(doc, name);
667 xmlAddID(NULL, doc, name, attr);
668 } else if(tmp != attr) {
669 xmlSecError(XMLSEC_ERRORS_HERE,
672 XMLSEC_ERRORS_R_INVALID_DATA,
673 "id=%s already defined",
674 xmlSecErrorsSafeString(name));
682 children = cur->children;
683 } else if(cur == NULL) {
684 children = doc->children;
687 while(children != NULL) {
688 if(children->type == XML_ELEMENT_NODE) {
689 xmlSecAddIDs(doc, children, ids);
691 children = children->next;
696 * xmlSecGenerateAndAddID:
697 * @node: the node to ID attr to.
698 * @attrName: the ID attr name.
699 * @prefix: the prefix to add to the generated ID (can be NULL).
700 * @len: the length of ID.
702 * Generates a unique ID in the format <@prefix>base64-encoded(@len random bytes)
703 * and puts it in the attribute @attrName.
705 * Returns: 0 on success or a negative value if an error occurs.
708 xmlSecGenerateAndAddID(xmlNodePtr node, const xmlChar* attrName, const xmlChar* prefix, xmlSecSize len) {
712 xmlSecAssert2(node != NULL, -1);
713 xmlSecAssert2(attrName != NULL, -1);
715 /* we will try 5 times before giving up */
716 for(count = 0; count < 5; count++) {
717 id = xmlSecGenerateID(prefix, len);
719 xmlSecError(XMLSEC_ERRORS_HERE,
722 XMLSEC_ERRORS_R_XMLSEC_FAILED,
723 XMLSEC_ERRORS_NO_MESSAGE);
727 if((node->doc == NULL) || (xmlGetID(node->doc, id) == NULL)) {
728 /* this is a unique ID in the document and we can use it */
729 if(xmlSetProp(node, attrName, id) == NULL) {
730 xmlSecError(XMLSEC_ERRORS_HERE,
733 XMLSEC_ERRORS_R_XML_FAILED,
734 XMLSEC_ERRORS_NO_MESSAGE);
750 * @prefix: the prefix to add to the generated ID (can be NULL).
751 * @len: the length of ID.
753 * Generates a unique ID in the format <@prefix>base64-encoded(@len random bytes).
754 * The caller is responsible for freeing returned string using @xmlFree function.
756 * Returns: pointer to generated ID string or NULL if an error occurs.
759 xmlSecGenerateID(const xmlChar* prefix, xmlSecSize len) {
761 xmlSecSize i, binLen;
766 xmlSecAssert2(len > 0, NULL);
768 /* we will do base64 decoding later */
769 binLen = (3 * len + 1) / 4;
771 ret = xmlSecBufferInitialize(&buffer, binLen + 1);
773 xmlSecError(XMLSEC_ERRORS_HERE,
775 "xmlSecBufferInitialize",
776 XMLSEC_ERRORS_R_XMLSEC_FAILED,
777 XMLSEC_ERRORS_NO_MESSAGE);
780 xmlSecAssert2(xmlSecBufferGetData(&buffer) != NULL, NULL);
781 xmlSecAssert2(xmlSecBufferGetMaxSize(&buffer) >= binLen, NULL);
783 ret = xmlSecBufferSetSize(&buffer, binLen);
785 xmlSecError(XMLSEC_ERRORS_HERE,
787 "xmlSecBufferSetSize",
788 XMLSEC_ERRORS_R_XMLSEC_FAILED,
789 XMLSEC_ERRORS_NO_MESSAGE);
790 xmlSecBufferFinalize(&buffer);
793 xmlSecAssert2(xmlSecBufferGetSize(&buffer) == binLen, NULL);
795 /* create random bytes */
796 for(i = 0; i < binLen; i++) {
797 (xmlSecBufferGetData(&buffer)) [i] = (xmlSecByte) (256.0 * rand() / (RAND_MAX + 1.0));
800 /* base64 encode random bytes */
801 res = xmlSecBase64Encode(xmlSecBufferGetData(&buffer), xmlSecBufferGetSize(&buffer), 0);
802 if((res == NULL) || (xmlStrlen(res) == 0)) {
803 xmlSecError(XMLSEC_ERRORS_HERE,
805 "xmlSecBase64Encode",
806 XMLSEC_ERRORS_R_XMLSEC_FAILED,
807 XMLSEC_ERRORS_NO_MESSAGE);
808 xmlSecBufferFinalize(&buffer);
811 xmlSecBufferFinalize(&buffer);
813 /* truncate the generated id attribute if needed */
814 if(xmlStrlen(res) > (int)len) {
818 /* we need to cleanup base64 encoded id because ID attr can't have '+' or '/' characters */
819 for(p = res; (*p) != '\0'; p++) {
820 if(((*p) == '+') || ((*p) == '/')) {
825 /* add prefix if exist */
830 tmpLen = xmlStrlen(prefix) + xmlStrlen(res) + 1;
831 tmp = xmlMalloc(tmpLen + 1);
833 xmlSecError(XMLSEC_ERRORS_HERE,
836 XMLSEC_ERRORS_R_MALLOC_FAILED,
837 XMLSEC_ERRORS_NO_MESSAGE);
842 xmlSecStrPrintf(tmp, tmpLen, BAD_CAST "%s%s", prefix, res);
846 /* no prefix: check that ID attribute starts from a letter */
847 if(!(((res[0] >= 'A') && (res[0] <= 'Z')) ||
848 ((res[0] >= 'a') && (res[0] <= 'z')))) {
859 * @rootNodeName: the root node name.
860 * @rootNodeNs: the root node namespace (otpional).
862 * Creates a new XML tree with one root node @rootNodeName.
864 * Returns: pointer to the newly created tree or NULL if an error occurs.
867 xmlSecCreateTree(const xmlChar* rootNodeName, const xmlChar* rootNodeNs) {
872 xmlSecAssert2(rootNodeName != NULL, NULL);
875 doc = xmlNewDoc(BAD_CAST "1.0");
877 xmlSecError(XMLSEC_ERRORS_HERE,
880 XMLSEC_ERRORS_R_XML_FAILED,
881 XMLSEC_ERRORS_NO_MESSAGE);
885 /* create root node */
886 root = xmlNewDocNode(doc, NULL, rootNodeName, NULL);
888 xmlSecError(XMLSEC_ERRORS_HERE,
891 XMLSEC_ERRORS_R_XML_FAILED,
896 xmlDocSetRootElement(doc, root);
898 /* and set root node namespace */
899 ns = xmlNewNs(root, rootNodeNs, NULL);
901 xmlSecError(XMLSEC_ERRORS_HERE,
904 XMLSEC_ERRORS_R_XML_FAILED,
906 xmlSecErrorsSafeString(rootNodeNs));
917 * @node: the node to check
919 * Checks whethere the @node is empty (i.e. has only whitespaces children).
921 * Returns: 1 if @node is empty, 0 otherwise or a negative value if an error occurs.
924 xmlSecIsEmptyNode(xmlNodePtr node) {
928 xmlSecAssert2(node != NULL, -1);
930 if(xmlSecGetNextElementNode(node->children) != NULL) {
934 content = xmlNodeGetContent(node);
935 if(content == NULL) {
939 res = xmlSecIsEmptyString(content);
945 * xmlSecIsEmptyString:
946 * @str: the string to check
948 * Checks whethere the @str is empty (i.e. has only whitespaces children).
950 * Returns: 1 if @str is empty, 0 otherwise or a negative value if an error occurs.
953 xmlSecIsEmptyString(const xmlChar* str) {
954 xmlSecAssert2(str != NULL, -1);
956 for( ;*str != '\0'; ++str) {
957 if(!isspace((int)(*str))) {
965 * xmlSecPrintXmlString:
966 * @fd: the file descriptor to write the XML string to
969 * Encodes the @str (e.g. replaces '&' with '&') and writes it to @fd.
971 * Returns: he number of bytes transmitted or a negative value if an error occurs.
974 xmlSecPrintXmlString(FILE * fd, const xmlChar * str) {
978 xmlChar * encoded_str = NULL;
979 encoded_str = xmlEncodeSpecialChars(NULL, str);
980 if(encoded_str == NULL) {
981 xmlSecError(XMLSEC_ERRORS_HERE,
983 "xmlEncodeSpecialChars",
984 XMLSEC_ERRORS_R_XML_FAILED,
986 xmlSecErrorsSafeString(str));
990 res = fprintf(fd, "%s", (const char*)encoded_str);
991 xmlFree(encoded_str);
993 res = fprintf(fd, "NULL");
997 xmlSecError(XMLSEC_ERRORS_HERE,
1000 XMLSEC_ERRORS_R_IO_FAILED,
1011 * @node: the context node.
1012 * @href: the QName href (can be NULL).
1013 * @local: the QName local part.
1015 * Creates QName (prefix:local) from @href and @local in the context of the @node.
1016 * Caller is responsible for freeing returned string with xmlFree.
1018 * Returns: qname or NULL if an error occurs.
1021 xmlSecGetQName(xmlNodePtr node, const xmlChar* href, const xmlChar* local) {
1025 xmlSecAssert2(node != NULL, NULL);
1026 xmlSecAssert2(local != NULL, NULL);
1028 /* we don't want to create namespace node ourselves because
1029 * it might cause collisions */
1030 ns = xmlSearchNsByHref(node->doc, node, href);
1031 if((ns == NULL) && (href != NULL)) {
1032 xmlSecError(XMLSEC_ERRORS_HERE,
1034 "xmlSearchNsByHref",
1035 XMLSEC_ERRORS_R_XML_FAILED,
1037 xmlSecErrorsSafeString(node->name),
1038 xmlSecErrorsSafeString(href));
1042 if((ns != NULL) && (ns->prefix != NULL)) {
1045 len = xmlStrlen(local) + xmlStrlen(ns->prefix) + 4;
1046 qname = xmlMalloc(len);
1048 xmlSecError(XMLSEC_ERRORS_HERE,
1051 XMLSEC_ERRORS_R_MALLOC_FAILED,
1053 xmlSecErrorsSafeString(node->name));
1056 xmlSecStrPrintf(qname, len, BAD_CAST "%s:%s", ns->prefix, local);
1058 qname = xmlStrdup(local);
1060 xmlSecError(XMLSEC_ERRORS_HERE,
1063 XMLSEC_ERRORS_R_MALLOC_FAILED,
1065 xmlSecErrorsSafeString(node->name));
1075 /*************************************************************************
1077 * QName <-> Integer mapping
1079 ************************************************************************/
1081 * xmlSecQName2IntegerGetInfo:
1082 * @info: the qname<->integer mapping information.
1083 * @intValue: the integer value.
1085 * Maps integer @intValue to a QName prefix.
1087 * Returns: the QName info that is mapped to @intValue or NULL if such value
1090 xmlSecQName2IntegerInfoConstPtr
1091 xmlSecQName2IntegerGetInfo(xmlSecQName2IntegerInfoConstPtr info, int intValue) {
1094 xmlSecAssert2(info != NULL, NULL);
1096 for(ii = 0; info[ii].qnameLocalPart != NULL; ii++) {
1097 if(info[ii].intValue == intValue) {
1106 * xmlSecQName2IntegerGetInteger:
1107 * @info: the qname<->integer mapping information.
1108 * @qnameHref: the qname href value.
1109 * @qnameLocalPart: the qname local part value.
1110 * @intValue: the pointer to result integer value.
1112 * Maps qname qname to an integer and returns it in @intValue.
1114 * Returns: 0 on success or a negative value if an error occurs,
1117 xmlSecQName2IntegerGetInteger(xmlSecQName2IntegerInfoConstPtr info,
1118 const xmlChar* qnameHref, const xmlChar* qnameLocalPart,
1122 xmlSecAssert2(info != NULL, -1);
1123 xmlSecAssert2(qnameLocalPart != NULL, -1);
1124 xmlSecAssert2(intValue != NULL, -1);
1126 for(ii = 0; info[ii].qnameLocalPart != NULL; ii++) {
1127 if(xmlStrEqual(info[ii].qnameLocalPart, qnameLocalPart) &&
1128 xmlStrEqual(info[ii].qnameHref, qnameHref)) {
1129 (*intValue) = info[ii].intValue;
1138 * xmlSecQName2IntegerGetIntegerFromString:
1139 * @info: the qname<->integer mapping information.
1140 * @node: the pointer to node.
1141 * @qname: the qname string.
1142 * @intValue: the pointer to result integer value.
1144 * Converts @qname into integer in context of @node.
1146 * Returns: 0 on success or a negative value if an error occurs,
1149 xmlSecQName2IntegerGetIntegerFromString(xmlSecQName2IntegerInfoConstPtr info,
1150 xmlNodePtr node, const xmlChar* qname,
1152 const xmlChar* qnameLocalPart = NULL;
1153 xmlChar* qnamePrefix = NULL;
1154 const xmlChar* qnameHref;
1158 xmlSecAssert2(info != NULL, -1);
1159 xmlSecAssert2(node != NULL, -1);
1160 xmlSecAssert2(qname != NULL, -1);
1161 xmlSecAssert2(intValue != NULL, -1);
1163 qnameLocalPart = xmlStrchr(qname, ':');
1164 if(qnameLocalPart != NULL) {
1165 qnamePrefix = xmlStrndup(qname, qnameLocalPart - qname);
1166 if(qnamePrefix == NULL) {
1167 xmlSecError(XMLSEC_ERRORS_HERE,
1170 XMLSEC_ERRORS_R_MALLOC_FAILED,
1172 xmlSecErrorsSafeString(node->name),
1173 xmlSecErrorsSafeString(qname));
1179 qnameLocalPart = qname;
1182 /* search namespace href */
1183 ns = xmlSearchNs(node->doc, node, qnamePrefix);
1184 if((ns == NULL) && (qnamePrefix != NULL)) {
1185 xmlSecError(XMLSEC_ERRORS_HERE,
1188 XMLSEC_ERRORS_R_XML_FAILED,
1189 "node=%s,qnamePrefix=%s",
1190 xmlSecErrorsSafeString(node->name),
1191 xmlSecErrorsSafeString(qnamePrefix));
1192 if(qnamePrefix != NULL) {
1193 xmlFree(qnamePrefix);
1197 qnameHref = (ns != NULL) ? ns->href : BAD_CAST NULL;
1199 /* and finally search for integer */
1200 ret = xmlSecQName2IntegerGetInteger(info, qnameHref, qnameLocalPart, intValue);
1202 xmlSecError(XMLSEC_ERRORS_HERE,
1204 "xmlSecQName2IntegerGetInteger",
1205 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1206 "node=%s,qnameLocalPart=%s,qnameHref=%s",
1207 xmlSecErrorsSafeString(node->name),
1208 xmlSecErrorsSafeString(qnameLocalPart),
1209 xmlSecErrorsSafeString(qnameHref));
1210 if(qnamePrefix != NULL) {
1211 xmlFree(qnamePrefix);
1216 if(qnamePrefix != NULL) {
1217 xmlFree(qnamePrefix);
1224 * xmlSecQName2IntegerGetStringFromInteger:
1225 * @info: the qname<->integer mapping information.
1226 * @node: the pointer to node.
1227 * @intValue: the integer value.
1229 * Creates qname string for @intValue in context of given @node. Caller
1230 * is responsible for freeing returned string with @xmlFree.
1232 * Returns: pointer to newly allocated string on success or NULL if an error occurs,
1235 xmlSecQName2IntegerGetStringFromInteger(xmlSecQName2IntegerInfoConstPtr info,
1236 xmlNodePtr node, int intValue) {
1237 xmlSecQName2IntegerInfoConstPtr qnameInfo;
1239 xmlSecAssert2(info != NULL, NULL);
1240 xmlSecAssert2(node != NULL, NULL);
1242 qnameInfo = xmlSecQName2IntegerGetInfo(info, intValue);
1243 if(qnameInfo == NULL) {
1244 xmlSecError(XMLSEC_ERRORS_HERE,
1246 "xmlSecQName2IntegerGetInfo",
1247 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1248 "node=%s,intValue=%d",
1249 xmlSecErrorsSafeString(node->name),
1254 return (xmlSecGetQName(node, qnameInfo->qnameHref, qnameInfo->qnameLocalPart));
1258 * xmlSecQName2IntegerNodeRead:
1259 * @info: the qname<->integer mapping information.
1260 * @node: the pointer to node.
1261 * @intValue: the pointer to result integer value.
1263 * Reads the content of @node and converts it to an integer using mapping
1266 * Returns: 0 on success or a negative value if an error occurs,
1269 xmlSecQName2IntegerNodeRead(xmlSecQName2IntegerInfoConstPtr info, xmlNodePtr node, int* intValue) {
1270 xmlChar* content = NULL;
1273 xmlSecAssert2(info != NULL, -1);
1274 xmlSecAssert2(node != NULL, -1);
1275 xmlSecAssert2(intValue != NULL, -1);
1277 content = xmlNodeGetContent(node);
1278 if(content == NULL) {
1279 xmlSecError(XMLSEC_ERRORS_HERE,
1281 "xmlNodeGetContent",
1282 XMLSEC_ERRORS_R_XML_FAILED,
1284 xmlSecErrorsSafeString(node->name));
1287 /* todo: trim content? */
1289 ret = xmlSecQName2IntegerGetIntegerFromString(info, node, content, intValue);
1291 xmlSecError(XMLSEC_ERRORS_HERE,
1293 "xmlSecQName2IntegerGetIntegerFromString",
1294 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1296 xmlSecErrorsSafeString(node->name),
1297 xmlSecErrorsSafeString(content));
1307 * xmlSecQName2IntegerNodeWrite:
1308 * @info: the qname<->integer mapping information.
1309 * @node: the parent node.
1310 * @nodeName: the child node name.
1311 * @nodeNs: the child node namespace.
1312 * @intValue: the integer value.
1314 * Creates new child node in @node and sets its value to @intValue.
1316 * Returns: 0 on success or a negative value if an error occurs,
1319 xmlSecQName2IntegerNodeWrite(xmlSecQName2IntegerInfoConstPtr info, xmlNodePtr node,
1320 const xmlChar* nodeName, const xmlChar* nodeNs, int intValue) {
1322 xmlChar* qname = NULL;
1324 xmlSecAssert2(info != NULL, -1);
1325 xmlSecAssert2(node != NULL, -1);
1326 xmlSecAssert2(nodeName != NULL, -1);
1328 /* find and build qname */
1329 qname = xmlSecQName2IntegerGetStringFromInteger(info, node, intValue);
1331 xmlSecError(XMLSEC_ERRORS_HERE,
1333 "xmlSecQName2IntegerGetStringFromInteger",
1334 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1335 "node=%s,intValue=%d",
1336 xmlSecErrorsSafeString(node->name),
1341 cur = xmlSecAddChild(node, nodeName, nodeNs);
1343 xmlSecError(XMLSEC_ERRORS_HERE,
1346 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1347 "node=%s,intValue=%d",
1348 xmlSecErrorsSafeString(nodeName),
1354 xmlNodeSetContent(cur, qname);
1360 * xmlSecQName2IntegerAttributeRead:
1361 * @info: the qname<->integer mapping information.
1362 * @node: the element node.
1363 * @attrName: the attribute name.
1364 * @intValue: the pointer to result integer value.
1366 * Gets the value of @attrName atrtibute from @node and converts it to integer
1367 * according to @info.
1369 * Returns: 0 on success or a negative value if an error occurs,
1372 xmlSecQName2IntegerAttributeRead(xmlSecQName2IntegerInfoConstPtr info, xmlNodePtr node,
1373 const xmlChar* attrName, int* intValue) {
1377 xmlSecAssert2(info != NULL, -1);
1378 xmlSecAssert2(node != NULL, -1);
1379 xmlSecAssert2(attrName != NULL, -1);
1380 xmlSecAssert2(intValue != NULL, -1);
1382 attrValue = xmlGetProp(node, attrName);
1383 if(attrValue == NULL) {
1384 xmlSecError(XMLSEC_ERRORS_HERE,
1387 XMLSEC_ERRORS_R_XML_FAILED,
1388 "node=%s,attrValue=%s",
1389 xmlSecErrorsSafeString(node->name),
1390 xmlSecErrorsSafeString(attrName));
1393 /* todo: trim value? */
1395 ret = xmlSecQName2IntegerGetIntegerFromString(info, node, attrValue, intValue);
1397 xmlSecError(XMLSEC_ERRORS_HERE,
1399 "xmlSecQName2IntegerGetIntegerFromString",
1400 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1401 "node=%s,attrName=%s,attrValue=%s",
1402 xmlSecErrorsSafeString(node->name),
1403 xmlSecErrorsSafeString(attrName),
1404 xmlSecErrorsSafeString(attrValue));
1414 * xmlSecQName2IntegerAttributeWrite:
1415 * @info: the qname<->integer mapping information.
1416 * @node: the parent node.
1417 * @attrName: the name of attribute.
1418 * @intValue: the integer value.
1420 * Converts @intValue to a qname and sets it to the value of
1421 * attribute @attrName in @node.
1423 * Returns: 0 on success or a negative value if an error occurs,
1426 xmlSecQName2IntegerAttributeWrite(xmlSecQName2IntegerInfoConstPtr info, xmlNodePtr node,
1427 const xmlChar* attrName, int intValue) {
1431 xmlSecAssert2(info != NULL, -1);
1432 xmlSecAssert2(node != NULL, -1);
1433 xmlSecAssert2(attrName != NULL, -1);
1435 /* find and build qname */
1436 qname = xmlSecQName2IntegerGetStringFromInteger(info, node, intValue);
1438 xmlSecError(XMLSEC_ERRORS_HERE,
1440 "xmlSecQName2IntegerGetStringFromInteger",
1441 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1442 "node=%s,attrName=%s,intValue=%d",
1443 xmlSecErrorsSafeString(node->name),
1444 xmlSecErrorsSafeString(attrName),
1449 attr = xmlSetProp(node, attrName, qname);
1451 xmlSecError(XMLSEC_ERRORS_HERE,
1453 "xmlSecAddChildNode",
1454 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1455 "node=%s,attrName=%s,intValue=%d",
1456 xmlSecErrorsSafeString(node->name),
1457 xmlSecErrorsSafeString(attrName),
1468 * xmlSecQName2IntegerDebugDump:
1469 * @info: the qname<->integer mapping information.
1470 * @intValue: the integer value.
1471 * @name: the value name to print.
1472 * @output: the pointer to output FILE.
1474 * Prints @intValue into @output.
1477 xmlSecQName2IntegerDebugDump(xmlSecQName2IntegerInfoConstPtr info, int intValue,
1478 const xmlChar* name, FILE* output) {
1479 xmlSecQName2IntegerInfoConstPtr qnameInfo;
1481 xmlSecAssert(info != NULL);
1482 xmlSecAssert(name != NULL);
1483 xmlSecAssert(output != NULL);
1485 qnameInfo = xmlSecQName2IntegerGetInfo(info, intValue);
1486 if(qnameInfo != NULL) {
1487 fprintf(output, "== %s: %d (name=\"%s\", href=\"%s\")\n", name, intValue,
1488 (qnameInfo->qnameLocalPart) ? qnameInfo->qnameLocalPart : BAD_CAST NULL,
1489 (qnameInfo->qnameHref) ? qnameInfo->qnameHref : BAD_CAST NULL);
1494 * xmlSecQName2IntegerDebugXmlDump:
1495 * @info: the qname<->integer mapping information.
1496 * @intValue: the integer value.
1497 * @name: the value name to print.
1498 * @output: the pointer to output FILE.
1500 * Prints @intValue into @output in XML format.
1503 xmlSecQName2IntegerDebugXmlDump(xmlSecQName2IntegerInfoConstPtr info, int intValue,
1504 const xmlChar* name, FILE* output) {
1505 xmlSecQName2IntegerInfoConstPtr qnameInfo;
1507 xmlSecAssert(info != NULL);
1508 xmlSecAssert(name != NULL);
1509 xmlSecAssert(output != NULL);
1511 qnameInfo = xmlSecQName2IntegerGetInfo(info, intValue);
1512 if(qnameInfo != NULL) {
1513 fprintf(output, "<%s value=\"%d\" href=\"%s\">%s<%s>\n", name, intValue,
1514 (qnameInfo->qnameHref) ? qnameInfo->qnameHref : BAD_CAST NULL,
1515 (qnameInfo->qnameLocalPart) ? qnameInfo->qnameLocalPart : BAD_CAST NULL,
1521 /*************************************************************************
1523 * QName <-> Bits mask mapping
1525 ************************************************************************/
1527 * xmlSecQName2BitMaskGetInfo:
1528 * @info: the qname<->bit mask mapping information.
1529 * @mask: the bit mask.
1531 * Converts @mask to qname.
1533 * Returns: pointer to the qname info for @mask or NULL if mask is unknown.
1535 xmlSecQName2BitMaskInfoConstPtr
1536 xmlSecQName2BitMaskGetInfo(xmlSecQName2BitMaskInfoConstPtr info, xmlSecBitMask mask) {
1539 xmlSecAssert2(info != NULL, NULL);
1541 for(ii = 0; info[ii].qnameLocalPart != NULL; ii++) {
1542 xmlSecAssert2(info[ii].mask != 0, NULL);
1543 if(info[ii].mask == mask) {
1552 * xmlSecQName2BitMaskGetBitMask:
1553 * @info: the qname<->bit mask mapping information.
1554 * @qnameHref: the qname Href value.
1555 * @qnameLocalPart: the qname LocalPart value.
1556 * @mask: the pointer to result mask.
1558 * Converts @qnameLocalPart to @mask.
1560 * Returns: 0 on success or a negative value if an error occurs,
1563 xmlSecQName2BitMaskGetBitMask(xmlSecQName2BitMaskInfoConstPtr info,
1564 const xmlChar* qnameHref, const xmlChar* qnameLocalPart,
1565 xmlSecBitMask* mask) {
1568 xmlSecAssert2(info != NULL, -1);
1569 xmlSecAssert2(qnameLocalPart != NULL, -1);
1570 xmlSecAssert2(mask != NULL, -1);
1572 for(ii = 0; info[ii].qnameLocalPart != NULL; ii++) {
1573 xmlSecAssert2(info[ii].mask != 0, -1);
1574 if(xmlStrEqual(info[ii].qnameLocalPart, qnameLocalPart) &&
1575 xmlStrEqual(info[ii].qnameHref, qnameHref)) {
1577 (*mask) = info[ii].mask;
1586 * xmlSecQName2BitMaskGetBitMaskFromString:
1587 * @info: the qname<->integer mapping information.
1588 * @node: the pointer to node.
1589 * @qname: the qname string.
1590 * @mask: the pointer to result msk value.
1592 * Converts @qname into integer in context of @node.
1594 * Returns: 0 on success or a negative value if an error occurs,
1597 xmlSecQName2BitMaskGetBitMaskFromString(xmlSecQName2BitMaskInfoConstPtr info,
1598 xmlNodePtr node, const xmlChar* qname,
1599 xmlSecBitMask* mask) {
1600 const xmlChar* qnameLocalPart = NULL;
1601 xmlChar* qnamePrefix = NULL;
1602 const xmlChar* qnameHref;
1606 xmlSecAssert2(info != NULL, -1);
1607 xmlSecAssert2(node != NULL, -1);
1608 xmlSecAssert2(qname != NULL, -1);
1609 xmlSecAssert2(mask != NULL, -1);
1611 qnameLocalPart = xmlStrchr(qname, ':');
1612 if(qnameLocalPart != NULL) {
1613 qnamePrefix = xmlStrndup(qname, qnameLocalPart - qname);
1614 if(qnamePrefix == NULL) {
1615 xmlSecError(XMLSEC_ERRORS_HERE,
1618 XMLSEC_ERRORS_R_MALLOC_FAILED,
1620 xmlSecErrorsSafeString(node->name),
1621 xmlSecErrorsSafeString(qname));
1627 qnameLocalPart = qname;
1630 /* search namespace href */
1631 ns = xmlSearchNs(node->doc, node, qnamePrefix);
1632 if((ns == NULL) && (qnamePrefix != NULL)) {
1633 xmlSecError(XMLSEC_ERRORS_HERE,
1636 XMLSEC_ERRORS_R_XML_FAILED,
1637 "node=%s,qnamePrefix=%s",
1638 xmlSecErrorsSafeString(node->name),
1639 xmlSecErrorsSafeString(qnamePrefix));
1640 if(qnamePrefix != NULL) {
1641 xmlFree(qnamePrefix);
1645 qnameHref = (ns != NULL) ? ns->href : BAD_CAST NULL;
1647 /* and finally search for integer */
1648 ret = xmlSecQName2BitMaskGetBitMask(info, qnameHref, qnameLocalPart, mask);
1650 xmlSecError(XMLSEC_ERRORS_HERE,
1652 "xmlSecQName2BitMaskGetBitMask",
1653 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1654 "node=%s,qnameLocalPart=%s,qnameHref=%s",
1655 xmlSecErrorsSafeString(node->name),
1656 xmlSecErrorsSafeString(qnameLocalPart),
1657 xmlSecErrorsSafeString(qnameHref));
1658 if(qnamePrefix != NULL) {
1659 xmlFree(qnamePrefix);
1664 if(qnamePrefix != NULL) {
1665 xmlFree(qnamePrefix);
1672 * xmlSecQName2BitMaskGetStringFromBitMask:
1673 * @info: the qname<->integer mapping information.
1674 * @node: the pointer to node.
1677 * Creates qname string for @mask in context of given @node. Caller
1678 * is responsible for freeing returned string with @xmlFree.
1680 * Returns: pointer to newly allocated string on success or NULL if an error occurs,
1683 xmlSecQName2BitMaskGetStringFromBitMask(xmlSecQName2BitMaskInfoConstPtr info,
1684 xmlNodePtr node, xmlSecBitMask mask) {
1685 xmlSecQName2BitMaskInfoConstPtr qnameInfo;
1687 xmlSecAssert2(info != NULL, NULL);
1688 xmlSecAssert2(node != NULL, NULL);
1690 qnameInfo = xmlSecQName2BitMaskGetInfo(info, mask);
1691 if(qnameInfo == NULL) {
1692 xmlSecError(XMLSEC_ERRORS_HERE,
1694 "xmlSecQName2BitMaskGetInfo",
1695 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1697 xmlSecErrorsSafeString(node->name),
1702 return(xmlSecGetQName(node, qnameInfo->qnameHref, qnameInfo->qnameLocalPart));
1706 * xmlSecQName2BitMaskNodesRead:
1707 * @info: the qname<->bit mask mapping information.
1709 * @nodeName: the mask nodes name.
1710 * @nodeNs: the mask nodes namespace.
1711 * @stopOnUnknown: if this flag is set then function exits if unknown
1713 * @mask: the pointer to result mask.
1715 * Reads <@nodeNs:@nodeName> elements and puts the result bit mask
1716 * into @mask. When function exits, @node points to the first element node
1717 * after all the <@nodeNs:@nodeName> elements.
1719 * Returns: 0 on success or a negative value if an error occurs,
1722 xmlSecQName2BitMaskNodesRead(xmlSecQName2BitMaskInfoConstPtr info, xmlNodePtr* node,
1723 const xmlChar* nodeName, const xmlChar* nodeNs,
1724 int stopOnUnknown, xmlSecBitMask* mask) {
1730 xmlSecAssert2(info != NULL, -1);
1731 xmlSecAssert2(node != NULL, -1);
1732 xmlSecAssert2(mask != NULL, -1);
1736 while((cur != NULL) && (xmlSecCheckNodeName(cur, nodeName, nodeNs))) {
1737 content = xmlNodeGetContent(cur);
1738 if(content == NULL) {
1739 xmlSecError(XMLSEC_ERRORS_HERE,
1741 "xmlNodeGetContent",
1742 XMLSEC_ERRORS_R_XML_FAILED,
1744 xmlSecErrorsSafeString(cur->name));
1748 ret = xmlSecQName2BitMaskGetBitMaskFromString(info, cur, content, &tmp);
1750 xmlSecError(XMLSEC_ERRORS_HERE,
1752 "xmlSecQName2BitMaskGetBitMaskFromString",
1753 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1755 xmlSecErrorsSafeString(content));
1761 if((stopOnUnknown != 0) && (tmp == 0)) {
1762 /* todo: better error */
1763 xmlSecError(XMLSEC_ERRORS_HERE,
1765 "xmlSecQName2BitMaskGetBitMaskFromString",
1766 XMLSEC_ERRORS_R_XMLSEC_FAILED,
1768 xmlSecErrorsSafeString(content));
1773 cur = xmlSecGetNextElementNode(cur->next);
1781 * xmlSecQName2BitMaskNodesWrite:
1782 * @info: the qname<->bit mask mapping information.
1783 * @node: the parent element for mask nodes.
1784 * @nodeName: the mask nodes name.
1785 * @nodeNs: the mask nodes namespace.
1786 * @mask: the bit mask.
1788 * Writes <@nodeNs:@nodeName> elemnts with values from @mask to @node.
1790 * Returns: 0 on success or a negative value if an error occurs,
1793 xmlSecQName2BitMaskNodesWrite(xmlSecQName2BitMaskInfoConstPtr info, xmlNodePtr node,
1794 const xmlChar* nodeName, const xmlChar* nodeNs,
1795 xmlSecBitMask mask) {
1798 xmlSecAssert2(info != NULL, -1);
1799 xmlSecAssert2(node != NULL, -1);
1800 xmlSecAssert2(nodeName != NULL, -1);
1802 for(ii = 0; (mask != 0) && (info[ii].qnameLocalPart != NULL); ii++) {
1803 xmlSecAssert2(info[ii].mask != 0, -1);
1805 if((mask & info[ii].mask) != 0) {
1809 qname = xmlSecGetQName(node, info[ii].qnameHref, info[ii].qnameLocalPart);
1811 xmlSecError(XMLSEC_ERRORS_HERE,
1814 XMLSEC_ERRORS_R_XML_FAILED,
1816 xmlSecErrorsSafeString(nodeName));
1820 cur = xmlSecAddChild(node, nodeName, nodeNs);
1822 xmlSecError(XMLSEC_ERRORS_HERE,
1825 XMLSEC_ERRORS_R_XML_FAILED,
1827 xmlSecErrorsSafeString(nodeName));
1832 xmlNodeSetContent(cur, qname);
1840 * xmlSecQName2BitMaskDebugDump:
1841 * @info: the qname<->bit mask mapping information.
1842 * @mask: the bit mask.
1843 * @name: the value name to print.
1844 * @output: the pointer to output FILE.
1846 * Prints debug information about @mask to @output.
1849 xmlSecQName2BitMaskDebugDump(xmlSecQName2BitMaskInfoConstPtr info, xmlSecBitMask mask,
1850 const xmlChar* name, FILE* output) {
1853 xmlSecAssert(info != NULL);
1854 xmlSecAssert(name != NULL);
1855 xmlSecAssert(output != NULL);
1861 fprintf(output, "== %s (0x%08x): ", name, mask);
1862 for(ii = 0; (mask != 0) && (info[ii].qnameLocalPart != NULL); ii++) {
1863 xmlSecAssert(info[ii].mask != 0);
1865 if((mask & info[ii].mask) != 0) {
1866 fprintf(output, "name=\"%s\" (href=\"%s\"),", info[ii].qnameLocalPart, info[ii].qnameHref);
1869 fprintf(output, "\n");
1873 * xmlSecQName2BitMaskDebugXmlDump:
1874 * @info: the qname<->bit mask mapping information.
1875 * @mask: the bit mask.
1876 * @name: the value name to print.
1877 * @output: the pointer to output FILE.
1879 * Prints debug information about @mask to @output in XML format.
1882 xmlSecQName2BitMaskDebugXmlDump(xmlSecQName2BitMaskInfoConstPtr info, xmlSecBitMask mask,
1883 const xmlChar* name, FILE* output) {
1886 xmlSecAssert(info != NULL);
1887 xmlSecAssert(name != NULL);
1888 xmlSecAssert(output != NULL);
1894 fprintf(output, "<%sList>\n", name);
1895 for(ii = 0; (mask != 0) && (info[ii].qnameLocalPart != NULL); ii++) {
1896 xmlSecAssert(info[ii].mask != 0);
1898 if((mask & info[ii].mask) != 0) {
1899 fprintf(output, "<%s href=\"%s\">%s</%s>\n", name,
1900 info[ii].qnameHref, info[ii].qnameLocalPart, name);
1903 fprintf(output, "</%sList>\n", name);