forked from instructure/nokogiri-xmlsec-instructure
-
Notifications
You must be signed in to change notification settings - Fork 0
/
nokogiri_helpers_set_attribute_id.c
96 lines (81 loc) · 2.51 KB
/
nokogiri_helpers_set_attribute_id.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include "xmlsecrb.h"
#include "util.h"
// declaration from Nokogiri proper
VALUE noko_xml_node_wrap(VALUE klass, xmlNodePtr node) ;
VALUE set_id_attribute(VALUE self, VALUE rb_attr_name) {
VALUE rb_exception_result = Qnil;
const char* exception_message = NULL;
xmlNodePtr node = NULL;
xmlAttrPtr attr = NULL;
xmlAttrPtr tmp = NULL;
xmlChar *name = NULL;
char *idName = NULL;
char *exception_attribute_arg = NULL;
resetXmlSecError();
Noko_Node_Get_Struct(self, xmlNode, node);
Check_Type(rb_attr_name, T_STRING);
idName = StringValueCStr(rb_attr_name);
// find pointer to id attribute
attr = xmlHasProp(node, (const xmlChar* )idName);
if((attr == NULL) || (attr->children == NULL)) {
rb_exception_result = rb_eRuntimeError;
exception_message = "Can't find attribute to add register as id";
goto done;
}
// get the attribute (id) value
name = xmlNodeListGetString(node->doc, attr->children, 1);
if(name == NULL) {
rb_exception_result = rb_eRuntimeError;
exception_message = "has no value";
exception_attribute_arg = idName;
goto done;
}
// check that we don't have that id already registered
tmp = xmlGetID(node->doc, name);
if(tmp != NULL) {
rb_exception_result = rb_eRuntimeError;
exception_message = "is already an ID";
exception_attribute_arg = idName;
goto done;
}
// finally register id
xmlAddID(NULL, node->doc, name, attr);
done:
// and do not forget to cleanup
if (name) {
xmlFree(name);
}
xmlSecErrorsSetCallback(xmlSecErrorsDefaultCallback);
if(rb_exception_result != Qnil) {
if (exception_attribute_arg) {
if (hasXmlSecLastError()) {
rb_raise(rb_exception_result, "Attribute %s %s, XmlSec error: %s",
exception_attribute_arg, exception_message, getXmlSecLastError());
} else {
rb_raise(rb_exception_result, "Attribute %s %s",
exception_attribute_arg, exception_message);
}
} else {
if (hasXmlSecLastError()) {
rb_raise(rb_exception_result, "%s, XmlSec error: %s", exception_message,
getXmlSecLastError());
} else {
rb_raise(rb_exception_result, "%s", exception_message);
}
}
}
return Qtrue;
}
VALUE get_id(VALUE self, VALUE rb_id)
{
xmlAttrPtr prop;
xmlDocPtr doc;
Check_Type(rb_id, T_STRING);
Noko_Node_Get_Struct(self, xmlDoc, doc);
prop = xmlGetID(doc, (const xmlChar *)StringValueCStr(rb_id));
if (prop) {
return noko_xml_node_wrap(Qnil, (xmlNodePtr)prop);
} else {
return Qnil;
}
}