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 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; }