static bool hidrd_xml_snk_put(hidrd_snk *snk, const hidrd_item *item) { bool result; hidrd_xml_snk_inst *xml_snk = (hidrd_xml_snk_inst *)snk; XML_ERR_FUNC_BACKUP_DECL; free(xml_snk->err); xml_snk->err = strdup(""); XML_ERR_FUNC_SET(&xml_snk->err); result = xml_snk_item_basic(xml_snk, item); XML_ERR_FUNC_RESTORE; return result; }
static bool hidrd_xml_snk_init(hidrd_snk *snk, char **perr, bool format, const char *schema) { bool result = false; hidrd_xml_snk_inst *xml_snk = (hidrd_xml_snk_inst *)snk; char *own_schema = NULL; hidrd_xml_snk_state *state = NULL; xmlDocPtr doc = NULL; xmlNodePtr root = NULL; xmlNsPtr ns; XML_ERR_FUNC_BACKUP_DECL; if (perr != NULL) *perr = strdup(""); XML_ERR_FUNC_SET(perr); /* Copy schema file path */ own_schema = strdup(schema); if (own_schema == NULL) XML_ERR_CLNP("failed to allocate memory for the schema file path"); /* Create item state table stack */ state = malloc(sizeof(*state)); if (state == NULL) XML_ERR_CLNP("failed to allocate memory for the state table"); state->prev = NULL; state->usage_page = HIDRD_USAGE_PAGE_UNDEFINED; /* Create the document */ doc = xmlNewDoc(BAD_CAST "1.0"); if (doc == NULL) goto cleanup; /* Create root node */ root = xmlNewNode(NULL, BAD_CAST "descriptor"); if (root == NULL) goto cleanup; /* Add and assign our namespace */ ns = xmlNewNs(root, BAD_CAST HIDRD_XML_PROP_NS, NULL); if (ns == NULL) goto cleanup; xmlSetNs(root, ns); /* Add XML schema instance namespace */ ns = xmlNewNs(root, BAD_CAST HIDRD_XML_PROP_NS_XSI, BAD_CAST "xsi"); if (ns == NULL) goto cleanup; /* Add xsi:schemaLocation attribute */ if (xmlSetNsProp(root, ns, BAD_CAST "schemaLocation", BAD_CAST HIDRD_XML_PROP_XSI_SCHEMA_LOCATION) == NULL) goto cleanup; /* Set root element */ xmlDocSetRootElement(doc, root); /* Initialize the sink */ xml_snk->schema = own_schema; xml_snk->format = format; xml_snk->state = state; xml_snk->doc = doc; xml_snk->prnt = root; xml_snk->err = strdup(""); own_schema = NULL; state = NULL; doc = NULL; root = NULL; result = true; cleanup: xmlFreeNode(root); if (doc != NULL) xmlFreeDoc(doc); free(state); free(own_schema); XML_ERR_FUNC_RESTORE; return result; }
static bool hidrd_xml_src_init(hidrd_src *src, char **perr, const char *schema) { bool result = false; hidrd_xml_src_inst *xml_src = (hidrd_xml_src_inst *)src; hidrd_xml_src_state *state = NULL; xmlDocPtr doc = NULL; bool valid; xmlNodePtr root; XML_ERR_FUNC_BACKUP_DECL; if (perr != NULL) *perr = strdup(""); XML_ERR_FUNC_SET(perr); /* Create item state table stack */ state = malloc(sizeof(*state)); if (state == NULL) XML_ERR_CLNP("failed to allocate memory for the state table"); state->prev = NULL; state->usage_page = HIDRD_USAGE_PAGE_UNDEFINED; /* Parse the document */ doc = xmlParseMemory(src->buf, src->size); if (doc == NULL) goto cleanup; /* Validate the document, if the schema is specified */ if (*schema != '\0' && (!xml_validate(&valid, doc, schema) || !valid)) goto cleanup; /* Retrieve the root element */ root = xmlDocGetRootElement(doc); if (root == NULL) XML_ERR_CLNP("root element not found"); /* Initialize the source */ xml_src->doc = doc; xml_src->prnt = NULL; xml_src->cur = root; xml_src->state = state; xml_src->err = strdup(""); /* Own the resources */ doc = NULL; state = NULL; /* Success */ result = true; cleanup: if (doc != NULL) xmlFreeDoc(doc); free(state); XML_ERR_FUNC_RESTORE; return result; }
static bool hidrd_xml_snk_flush(hidrd_snk *snk) { bool result = false; hidrd_xml_snk_inst *xml_snk = (hidrd_xml_snk_inst *)snk; bool valid; xmlBufferPtr xml_buf = NULL; xmlOutputBufferPtr xml_out_buf = NULL; void *new_buf; size_t new_size; XML_ERR_FUNC_BACKUP_DECL; free(xml_snk->err); xml_snk->err = strdup(""); XML_ERR_FUNC_SET(&xml_snk->err); /* Break any unfinished groups */ if (!xml_snk_group_break_branch(snk)) goto cleanup; /* Validate the document, if the schema is specified */ if (*xml_snk->schema != '\0' && (!xml_validate(&valid, xml_snk->doc, xml_snk->schema) || !valid)) goto cleanup; /* Create an XML buffer */ xml_buf = xmlBufferCreate(); if (xml_buf == NULL) goto cleanup; /* Create an XML output buffer from the generic buffer */ xml_out_buf = xmlOutputBufferCreateBuffer(xml_buf, NULL); if (xml_out_buf == NULL) goto cleanup; /* Format XML from the document */ if (xmlSaveFormatFileTo(xml_out_buf, xml_snk->doc, NULL, xml_snk->format) < 0) goto cleanup; /* xml_out_buf is closed by xmlSaveFormatFileTo */ xml_out_buf = NULL; /* Retrieve resulting size */ new_size = xmlBufferLength(xml_buf); /* If we have a location for the buffer pointer */ if (snk->pbuf != NULL) { /* Retention and update the buffer */ new_buf = realloc(*snk->pbuf, new_size); if (new_size > 0 && new_buf == NULL) XML_ERR_CLNP("failed to retention the output buffer"); memcpy(new_buf, xmlBufferContent(xml_buf), new_size); /* Update the buffer pointer */ *snk->pbuf = new_buf; } /* Output size */ if (snk->psize != NULL) *snk->psize = new_size; result = true; cleanup: if (xml_out_buf != NULL) xmlOutputBufferClose(xml_out_buf); if (xml_buf != NULL) xmlBufferFree(xml_buf); XML_ERR_FUNC_RESTORE; return result; }
static const hidrd_item * hidrd_xml_src_get(hidrd_src *src) { const hidrd_item *result = NULL; hidrd_xml_src_inst *xml_src = (hidrd_xml_src_inst *)src; xml_src_element_rc rc; bool enter; XML_ERR_FUNC_BACKUP_DECL; free(xml_src->err); xml_src->err = strdup(""); XML_ERR_FUNC_SET(&xml_src->err); do { /* * Get next element (go forward and up). */ while (true) { /* While we're at the end of the node list */ while (xml_src->cur == NULL) { /* We don't go above the root element (only start there) */ assert(xml_src->prnt != NULL); /* Handle the exit from an element */ rc = xml_src_element_exit(xml_src); /* If an error occurred */ if (rc == XML_SRC_ELEMENT_RC_ERROR) xml_src->src.error = true; /* If we shouldn't stop here */ if (rc != XML_SRC_ELEMENT_RC_ERROR && rc != XML_SRC_ELEMENT_RC_END) { /* Go up (exit) */ xml_src->cur = xml_src->prnt->next; xml_src->prnt = xml_src->prnt->parent; /* * We don't go above the root element (only start there) */ assert(xml_src->prnt != NULL); } /* If we have something to return */ if (rc != XML_SRC_ELEMENT_RC_NONE) { if (rc == XML_SRC_ELEMENT_RC_ITEM) result = hidrd_item_validate(xml_src->item); goto cleanup; } } /* If this node is an element */ if (xml_src->cur->type == XML_ELEMENT_NODE) break; /* Get next node */ xml_src->cur = xml_src->cur->next; } /* * Process the element */ enter = false; rc = xml_src_element(xml_src, &enter); /* If an error occurred */ if (rc == XML_SRC_ELEMENT_RC_ERROR) xml_src->src.error = true; /* If we shouldn't stop here */ if (rc != XML_SRC_ELEMENT_RC_ERROR && rc != XML_SRC_ELEMENT_RC_END) { if (enter) { xml_src->prnt = xml_src->cur; xml_src->cur = xml_src->prnt->children; } else xml_src->cur = xml_src->cur->next; } } while (rc == XML_SRC_ELEMENT_RC_NONE); /* While nothing to return */ if (rc == XML_SRC_ELEMENT_RC_ITEM) result = hidrd_item_validate(xml_src->item); cleanup: XML_ERR_FUNC_RESTORE; return result; }