Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}
Exemple #4
0
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;
}
Exemple #5
0
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;
}