/*
 * Parse an element node. Check if there is a token for an element tag; if not
 * output the element as a string, else ouput the token. After that, call 
 * attribute parsing functions
 * Returns:      1, add an end tag (element node has no children)
 *               0, do not add an end tag (it has children)
 *              -1, an error occurred
 */
static int parse_element(xmlNodePtr node, simple_binary_t **sibxml)
{
    Octstr *name,
           *outos;
    size_t i;
    unsigned char status_bits,
             si_hex;
    int add_end_tag;
    xmlAttrPtr attribute;

    name = octstr_create((char *)node->name);
    outos = NULL;
    if (octstr_len(name) == 0) {
        octstr_destroy(name);
        return -1;
    }

    i = 0;
    while (i < NUMBER_OF_ELEMENTS) {
        if (octstr_compare(name, octstr_imm(si_elements[i].name)) == 0)
            break;
        ++i;
    }

    status_bits = 0x00;
    si_hex = 0x00;
    add_end_tag = 0;

    if (i != NUMBER_OF_ELEMENTS) {
        si_hex = si_elements[i].token;
        if ((status_bits = element_check_content(node)) > 0) {
	    si_hex = si_hex | status_bits;
	    
	    if ((status_bits & WBXML_CONTENT_BIT) == WBXML_CONTENT_BIT)
	        add_end_tag = 1;
        }
        output_char(si_hex, sibxml);
    } else {
        warning(0, "unknown tag %s in SI source", octstr_get_cstr(name));
        si_hex = WBXML_LITERAL;
        if ((status_bits = element_check_content(node)) > 0) {
	    si_hex = si_hex | status_bits;
	    /* If this node has children, the end tag must be added after 
	       them. */
	    if ((status_bits & WBXML_CONTENT_BIT) == WBXML_CONTENT_BIT)
		add_end_tag = 1;
	}
	output_char(si_hex, sibxml);
        output_octet_string(outos = octstr_duplicate(name), sibxml);
    }

    if (node->properties != NULL) {
	attribute = node->properties;
	while (attribute != NULL) {
	    parse_attribute(attribute, sibxml);
	    attribute = attribute->next;
	}
	parse_end(sibxml);
    }

    octstr_destroy(outos);
    octstr_destroy(name);
    return add_end_tag;
}
Beispiel #2
0
/*
 * Tokenises an attribute, and in most cases, the start of its value (some-
 * times whole of it). Tokenisation is based on tables in si, chapters 9.3.2
 * and 9.3.3. 
 * Returns 0 when success, -1 when error.
 */
static int parse_attribute(xmlAttrPtr attr, simple_binary_t **sibxml)
{
    Octstr *name,
           *value,
           *valueos,
           *tokenized_date;
    unsigned char si_hex;
    size_t i,
           value_len;

    name = octstr_create((char *)attr->name);

    if (attr->children != NULL)
	value = create_octstr_from_node((char *)attr->children);
    else 
	value = NULL;

    if (value == NULL)
        goto error;

    i = 0;
    valueos = NULL;
    while (i < NUMBER_OF_ATTRIBUTES) {
        if (octstr_compare(name, octstr_imm(si_attributes[i].name)) == 0) {
	    if (si_attributes[i].value_part == NULL) {
	        break; 
            } else {
                value_len = octstr_len(valueos = 
                    octstr_imm(si_attributes[i].value_part));
	        if (octstr_ncompare(value, valueos, value_len) == 0) {
		    break;
                }
            }
        }
       ++i;
    }

    if (i == NUMBER_OF_ATTRIBUTES)
        goto error;

    tokenized_date = NULL;
    si_hex = si_attributes[i].token;
    if (action(si_hex)) {
        output_char(si_hex, sibxml);
    } else if (url(si_hex)) {
        output_char(si_hex, sibxml);
        octstr_delete(value, 0, octstr_len(valueos));
        parse_url_value(value, sibxml);
    } else if (date(si_hex)) {
        if ((tokenized_date = tokenize_date(value)) == NULL)
            goto error;
        output_char(si_hex, sibxml);
        output_octet_string(tokenized_date, sibxml);
    } else {
        output_char(si_hex, sibxml);
        parse_inline_string(value, sibxml);
    }  

    octstr_destroy(tokenized_date);
    octstr_destroy(name);
    octstr_destroy(value);
    return 0;

error:
    octstr_destroy(name);
    octstr_destroy(value);
    return -1;
}