⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wml_compiler.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 4 页
字号:
	break;    }    /*      * If node is an element with content, it will need an end tag after it's     * children. The status for it is returned by parse_element.     */    switch (status) {    case 0:	if (node->children != NULL)	    if (parse_node(node->children, wbxml) == -1)		return -1;	break;    case 1:	if (node->children != NULL)	    if (parse_node(node->children, wbxml) == -1)		return -1;	parse_st_end(wbxml);	break;    case -1: /* Something went wrong in the parsing. */	return -1;    default:	error(0,	      "WML compiler: undefined return value in a parse function.");	return -1;	break;    }    if (node->next != NULL)	if (parse_node(node->next, wbxml) == -1)	    return -1;    return 0;}/* * parse_document - the parsing function for the document node. * The function outputs the WBXML version, WML public id and the * character set values into start of the wbxml. */static int parse_document(xmlDocPtr document, Octstr *charset,                          wml_binary_t **wbxml, Octstr *version){    xmlNodePtr node;    Octstr *externalID = NULL;    long i;    if (document == NULL) {        error(0, "WML compiler: XML parsing failed, no parsed document.");        error(0, "Most probably an error in the WML source.");        return -1;    }    /* Return WBXML version dependent on device given Encoding-Version */    if (version == NULL) {        (*wbxml)->wbxml_version = 0x01; /* WBXML Version number 1.1 */        info(0, "WBXML: No wbxml version given, assuming 1.1");    } else {        for (i = 0; i < NUMBER_OF_WBXML_VERSION; i++) {            if (octstr_compare(version, octstr_imm(wbxml_version[i].string)) == 0) {                (*wbxml)->wbxml_version = wbxml_version[i].value;                debug("parse_document",0,"WBXML: Encoding with wbxml version <%s>",                      octstr_get_cstr(version));                break;            }        }        if (i == NUMBER_OF_WBXML_VERSION) {            (*wbxml)->wbxml_version = 0x01; /* WBXML Version number 1.1 */            warning(0, "WBXML: Unknown wbxml version, assuming 1.1 (<%s> is unknown)",                    octstr_get_cstr(version));        }    }    /* Return WML Version dependent on xml ExternalID string */    if ((document->intSubset != NULL) && (document->intSubset->ExternalID != NULL))            externalID = octstr_create(document->intSubset->ExternalID);    if (externalID == NULL) {        (*wbxml)->wml_public_id = 0x04; /* WML 1.1 Public ID */        warning(0, "WBXML: WML without ExternalID, assuming 1.1");    } else {        for (i = 0; i < NUMBER_OF_WML_EXTERNALID; i++) {            if (octstr_compare(externalID, octstr_imm(wml_externalid[i].string)) == 0) {                (*wbxml)->wml_public_id = wml_externalid[i].value;                debug("parse_document",0,"WBXML: WML with ExternalID <%s>",                      octstr_get_cstr(externalID));                break;            }        }        if (i == NUMBER_OF_WML_EXTERNALID) {            (*wbxml)->wml_public_id = 0x04; /* WML 1.1 Public ID */            warning(0, "WBXML: WML with unknown ExternalID, assuming 1.1 "                    "(<%s> is unknown)",                    octstr_get_cstr(externalID));        }    }    octstr_destroy(externalID);        (*wbxml)->string_table_length = 0x00; /* String table length=0 */    /*     * Make sure we set the charset encoding right. If none is given     * then set UTF-8 as default.     */    (*wbxml)->character_set = charset ?         parse_charset(charset) : parse_charset(octstr_imm("UTF-8"));    node = xmlDocGetRootElement(document);    string_table_build(node, wbxml);    return parse_node(node, wbxml);}/* * parse_element - the parsing function for an element node. * The element tag is encoded into one octet hexadecimal value,  * if possible. Otherwise it is encoded as text. If the element  * needs an end tag, the function returns 1, for no end tag 0 * and -1 for an error. */static int parse_element(xmlNodePtr node, wml_binary_t **wbxml){    int add_end_tag = 0;    unsigned char wbxml_hex = 0, status_bits;    xmlAttrPtr attribute;    Octstr *name;    wml_hash_t *element;    name = octstr_create(node->name);    /* Check, if the tag can be found from the code page. */    if ((element = dict_get(wml_elements_dict, name)) != NULL) {	wbxml_hex = element->binary;	/* A conformance patch: no do-elements of same name in a card or	   template. An extremely ugly patch. --tuo */	if (wbxml_hex == 0x27 || /* Card */	    wbxml_hex == 0x3B)   /* Template */	    if (check_do_elements(node) == -1) {		add_end_tag = -1;		error(0, "WML compiler: Two or more do elements with same"		      " name in a card or template element.");	    }	/* A conformance patch: if variable in setvar has a bad name, it's	   ignored. */	if (wbxml_hex == 0x3E) /* Setvar */	    if (check_variable_name(node) == FAILED) {		octstr_destroy(name);		return add_end_tag;	    }	if ((status_bits = element_check_content(node)) > 0) {	    wbxml_hex = wbxml_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_st_char(wbxml_hex, wbxml);    } else {    	/* The tag was not on the code page, it has to be encoded as a 	   string. */	wbxml_hex = WBXML_LITERAL;	if ((status_bits = element_check_content(node)) > 0) {	    wbxml_hex = wbxml_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_st_char(wbxml_hex, wbxml);	octstr_append_uintvar((*wbxml)->wbxml_string,string_table_add(octstr_duplicate(name), wbxml));	warning(0, "WML compiler: Unknown tag in WML source: <%s>", 		octstr_get_cstr(name));    }    /* Encode the attribute list for this node and add end tag after the        list. */    if(node->properties != NULL) {	attribute = node->properties;	while (attribute != NULL) {	    parse_attribute(attribute, wbxml);	    attribute = attribute->next;	}	parse_st_end(wbxml);    }    octstr_destroy(name);    return add_end_tag;}/* * parse_attribute - the parsing function for attributes. The function  * encodes the attribute (and probably start of the value) as a one  * hexadecimal octet. The value (or the rest of it) is coded as a string  * maybe using predefined attribute value tokens to reduce the length * of the output. Returns 0 for success, -1 for error. */static int parse_attribute(xmlAttrPtr attr, wml_binary_t **wbxml){    int status = 0;    int coded_length = 0;    unsigned char wbxml_hex = 0x00;    wml_hash_t *hit = NULL;    wml_attribute_t *attribute = NULL;    Octstr *name = NULL, *pattern = NULL, *p = NULL;    name = octstr_create(attr->name);    if (attr->children != NULL)	pattern = create_octstr_from_node(attr->children);    else 	pattern = NULL;    /* Check if the attribute is found on the code page. */    if ((attribute = dict_get(wml_attributes_dict, name)) != NULL) {	if (attr->children == NULL || 	    (hit = list_search(attribute->value_list, (void *)pattern, 			       hash_cmp)) == NULL) {                if(attribute->binary == 0x00) {                    warning(0, "WML compiler: can't compile attribute %s%s%s%s",                                octstr_get_cstr(attribute->attribute), 			       (attr->children != NULL ? "=\"": ""), 			       (attr->children != NULL ? octstr_get_cstr(pattern) : ""), 			       (attr->children != NULL ? "\"": ""));	            wbxml_hex = WBXML_LITERAL;	            output_st_char(wbxml_hex, wbxml);	            output_st_char(string_table_add(octstr_duplicate(name), wbxml), wbxml);		} else {		    wbxml_hex = attribute->binary;		    output_st_char(wbxml_hex, wbxml);		}	} else if (hit->binary) {	    wbxml_hex = hit->binary;	    coded_length = octstr_len(hit->item);	    output_st_char(wbxml_hex, wbxml);	} else	    status = -1;    } else {	/* The attribute was not on the code page, it has to be encoded as a 	   string. */	wbxml_hex = WBXML_LITERAL;	output_st_char(wbxml_hex, wbxml);	octstr_append_uintvar((*wbxml)->wbxml_string,string_table_add(octstr_duplicate(name), wbxml));	warning(0, "WML compiler: Unknown attribute in WML source: <%s>", 		octstr_get_cstr(name));    }    if (status >= 0) {	var_esc_t default_esc;	default_esc = (octstr_str_compare (name, "href") == 0) ? ESC : NOESC;	/* The rest of the attribute is coded as a inline string. */	if (pattern != NULL && 	    coded_length < (int) octstr_len(pattern)) {	    if (coded_length == 0)		p = create_octstr_from_node(attr->children); 	    else		p = octstr_copy(pattern, coded_length, 				octstr_len(pattern) - coded_length); 	    if (check_if_url(wbxml_hex))		status = parse_attr_value(p, wml_URL_values_list,					  wbxml, attr->doc->charset, default_esc);	    else		status = parse_attr_value(p, wml_attr_values_list,					  wbxml, attr->doc->charset, default_esc);	    if (status != 0)		error(0, 		      "WML compiler: could not output attribute "		      "value as a string.");	    octstr_destroy(p);	}    }    /* Memory cleanup. */    octstr_destroy(name);    if (pattern != NULL)	octstr_destroy(pattern);    return status;}/* * parse_attr_value - parses an attributes value using WML value codes. */static int parse_attr_value(Octstr *attr_value, List *tokens,			    wml_binary_t **wbxml, int charset, var_esc_t default_esc){    int i, pos, wbxml_hex;    wml_hash_t *temp = NULL;    Octstr *cut_text = NULL;    char *tmp;    /*     * Beware that libxml2 does internal encoding in UTF-8 while parsing.     * So if our original WML source had a different encoding set, we have     * to transcode at least here. Only transcode if target encoding differs     * from libxml2's internal encoding (UTF-8).     */    tmp = (char*) xmlGetCharEncodingName(charset);    if (charset != XML_CHAR_ENCODING_UTF8 &&         charset_convert(attr_value, "UTF-8",                         tmp) != 0) {        error(0, "Failed to convert XML attribute value from charset "                 "<%s> to <%s>, will leave as is.", "UTF-8",                  tmp ? tmp : "(undef)");    }    /*     * The attribute value is search for text strings that can be replaced      * with one byte codes. Note that the algorith is not foolproof; seaching      * is done in an order and the text before first hit is not checked for      * those tokens that are after the hit in the order. Most likely it would      * be waste of time anyway. String table is not used here, since at least      * Nokia 7110 doesn't seem to understand string table references here.     */    /* A fast patch to allow reserved names to be variable names. May produce        a little longer binary at some points. --tuo */    if (octstr_search_char(attr_value, '$', 0) >= 0) {	if (parse_st_octet_string(attr_value, 0, default_esc, wbxml) != 0)	    return -1;    } else {	for (i = 0; i < list_len(tokens); i++) {	    temp = list_get(tokens, i);	    pos = octstr_search(attr_value, temp->item, 0);	    switch (pos) {	    case -1:		break;	    case 0:		wbxml_hex = temp->binary;		output_st_char(wbxml_hex, wbxml);			octstr_delete(attr_value, 0, octstr_len(temp->item));			break;	    default:		/* 		 *  There is some text before the first hit, that has to 		 *  be handled too. 		 */		gw_assert(pos <= octstr_len(attr_value));			cut_text = octstr_copy(attr_value, 0, pos);		if (parse_st_octet_string(cut_text, 0, default_esc, wbxml) != 0)		    return -1;		octstr_destroy(cut_text);	    		wbxml_hex = temp->binary;		output_st_char(wbxml_hex, wbxml);			octstr_delete(attr_value, 0, pos + octstr_len(temp->item));		break;	    }	}	/* 	 * If no hits, then the attr_value is handled as a normal text, 	 * otherwise the remaining part is searched for other hits too. 	 */	if ((int) octstr_len(attr_value) > 0) {	    if (i < list_len(tokens))		parse_attr_value(attr_value, tokens, wbxml, charset, default_esc);	    else		if (parse_st_octet_string(attr_value, 0, default_esc, wbxml) != 0)		    return -1;	}    }    return 0;}/* * parse_st_end - adds end tag to an element. */static void parse_st_end(wml_binary_t **wbxml){    output_st_char(WBXML_END, wbxml);}/* * parse_text - a text string parsing function. * This function parses a text node.  */static int parse_text(xmlNodePtr node, wml_binary_t **wbxml){    int ret;    Octstr *temp;    char* tmp;    temp = create_octstr_from_node(node); /* returns string in UTF-8 */    /*     * Beware that libxml2 does internal encoding in UTF-8 while parsing.     * So if our original WML source had a different encoding set, we have     * to transcode at least here. Only transcode if target encoding differs     * from libxml2's internal encoding (UTF-8).     */    tmp = (char*) xmlGetCharEncodingName(node->doc->charset);    if (node->doc->charset != XML_CHAR_ENCODING_UTF8 &&         charset_convert(temp, "UTF-8",                         tmp) != 0) {        error(0, "Failed to convert XML text entity from charset "                 "<%s> to <%s>, will leave as is.", "UTF-8",                  tmp ? tmp : "(undef)");    }    octstr_shrink_blanks(temp);    if (!check_if_emphasis(node->prev) && !check_if_emphasis(node->next))	octstr_strip_blanks(temp);    if (octstr_len(temp) == 0)        ret = 0;    else         ret = parse_st_octet_string(temp, 0, NOESC, wbxml);    /* Memory cleanup. */    octstr_destroy(temp);    return ret;}/* * parse_cdata - a cdata section parsing function. * This function parses a cdata section that is outputted into the binary  * "as is".  */static int parse_cdata(xmlNodePtr node, wml_binary_t **wbxml){    int ret = 0;    Octstr *temp;    temp = create_octstr_from_node(node);    parse_st_octet_string(temp, 1, NOESC, wbxml);        /* Memory cleanup. */    octstr_destroy(temp);    return ret;}/* * parse_variable - a variable parsing function.  * Arguments: * - text: the octet string containing a variable * - start: the starting position of the variable not including  *   trailing & * Returns: lenth of the variable for success, -1 for failure, 0 for  * variable syntax error, when it will be ignored.  * Parsed variable is returned as an octet string in Octstr **output. */static int parse_variable(Octstr *text, int start, var_esc_t default_esc, Octstr **output, 			  wml_binary_t **wbxml){    var_esc_t esc;    int ret;    Octstr *variable;    variable = get_variable(text, start + 1);    octstr_truncate(*output, 0);    if (variable == NULL)	return 0;    if (octstr_get_char(variable, 0) == '$') {	octstr_append_char(*output, '$');	octstr_destroy(variable);	ret = 2;    } else {	if (octstr_get_char(text, start + 1) == '(')	    ret = octstr_len(variable) + 3;	else	    ret = octstr_len(variable) + 1;	if ((esc = check_variable_syntax(variable, default_esc)) != FAILED)	    output_variable(variable, output, esc, wbxml);	else	    octstr_destroy(variable);    }    return ret;}/* * get_variable - get the variable name from text. * Octstr *text contains the text with a variable name starting at point  * int start. */static Octstr *get_variable(Octstr *text, int start){    Octstr *var = NULL;    long end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -