[Libvirt-cim] [PATCH 2 of 3] [RFC][CU] Add EI CIMXML parser
Daniel Veillard
veillard at redhat.com
Sun Feb 10 21:07:27 UTC 2008
On Fri, Feb 08, 2008 at 03:18:00PM -0800, Dan Smith wrote:
> # HG changeset patch
> # User Dan Smith <danms at us.ibm.com>
> # Date 1202512655 28800
> # Node ID f6559a2f55abab85baeabd56faaf7804c3ea30f3
> # Parent 03126c9af41607dcaa8b197736dd5059c108261a
> [RFC][CU] Add EI CIMXML parser
>
> This handles strings, bools, integers, and arrays of those. It doesn't yet
> handle nested objects, as we will need for RASD.HostResource[]. I need
> to do some further investigation of what the XML for that will look like.
>
> I have tested this by taking an existing XML for DefineSystem() and
> changing the MemResourceAllocationSettingData field to this:
>
> <INSTANCE CLASSNAME="Xen_MemResourceAllocationSettingData">
> <PROPERTY NAME="CreationClassName" TYPE="string">
> <VALUE>Xen_MemResourceAllocationSettingData</VALUE>
> </PROPERTY>
> <PROPERTY NAME="InstanceID" TYPE="string">
> <VALUE>test/mem</VALUE>
> </PROPERTY>
> <PROPERTY NAME="ResourceType" TYPE="uint16">
> <VALUE>4</VALUE>
> </PROPERTY>
> <PROPERTY NAME="VirtualQuantity" TYPE="uint64">
> <VALUE>256 </VALUE>
> </PROPERTY>
> <PROPERTY.ARRAY NAME="Foo" TYPE="string">
> <VALUE.ARRAY>
> <VALUE>Bar</VALUE>
> <VALUE>Baz</VALUE>
> </VALUE.ARRAY>
> </PROPERTY.ARRAY>
> </INSTANCE>
Oh the escaping fun :-)
[...]
> +static CMPIType get_node_value(const CMPIBroker *broker,
> + xmlNode *node,
> + const char *tstr,
> + CMPIValue *val)
> +{
> + CMPIType type = CMPI_null;
> + char *content = NULL;
> +
> + if (node->type != XML_ELEMENT_NODE) {
> + CU_DEBUG("Non-element node: %s", node->name);
> + goto out;
> + }
> +
> + if (!STREQC((char *)node->name, "value")) {
> + CU_DEBUG("Expected <VALUE> but got <%s>", node->name);
> + goto out;
> + }
Assuming I understand the example, there is also no namespace in those
element, checking node->ns == NULL might be a good idea (or not if namespaced)
> + content = get_content(node);
> + CU_DEBUG("Node content: %s", content);
> + type = get_property_value(broker, tstr, content, val);
> + free(content);
> + out:
> + return type;
> +}
> +
> +static CMPIType parse_array(const CMPIBroker *broker,
> + const char *tstr,
> + xmlNode *root,
> + CMPIArray **array)
> +{
> + xmlNode *value;
> + CMPIValue *list = NULL;
> + int size = 0;
> + int cur = 0;
> + CMPIStatus s;
> + CMPIType type = CMPI_null;
> + int i;
> +
> + for (value = root->children; value; value = value->next) {
> +
> + if (value->type != XML_ELEMENT_NODE)
> + continue;
> +
> + if (cur == size) {
> + CMPIValue *tmp;
> +
> + size += 4;
> + tmp = realloc(list, sizeof(CMPIValue) * size);
when i have realloc in loop I usually do things like size *= 2 to escape
a linear growing model.
[..]
> + for (child = root->children; child; child = child->next) {
> + if (child->type == XML_ELEMENT_NODE){
check namespace here ?
> + if (STREQC((char *)child->name, "property"))
> + parse_property(broker, child, *inst);
> + CU_DEBUG("Escape is: %s", escape);
> +
> + if (STREQC(escape, "<"))
> + *result = '<';
> + else if (STREQC(escape, ">"))
> + *result = '>';
> + else if (STREQC(escape, """))
> + *result = '\"';
Add & -> & and ' -> ''' would be good for completeness
[...]
> +int cu_parse_ei_xml(const CMPIBroker *broker,
> + const char *ns,
> + const char *xml,
> + CMPIInstance **instance)
> +{
> + xmlDoc *doc = NULL;
> + xmlNode *root = NULL;
> + int ret = 0;
> +
> + doc = xmlReadMemory(xml, strlen(xml), NULL, NULL, 0);
I would add (XML_PARSE_NOENT | XML_PARSE_NOCDATA | XML_PARSE_NONET)
to ask the parser to replace entities references, change CDATA section into
normal text and forbid network access (should not occur, but better safe than
sorry :-)
> + if (doc == NULL) {
> + CU_DEBUG("Error reading decoded XML from memory");
> + goto out;
> + }
> +
> + root = xmlDocGetRootElement(doc);
> + if (root == NULL) {
> + CU_DEBUG("Error getting root XML node");
> + goto out;
> + }
> +
Looks fine, maybe a small check that no memory allocation is lost is in
order though, it's easy to forget something.
Daniel
--
Red Hat Virtualization group http://redhat.com/virtualization/
Daniel Veillard | virtualization library http://libvirt.org/
veillard at redhat.com | libxml GNOME XML XSLT toolkit http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/
More information about the Libvirt-cim
mailing list