📄 wap_push_si_compiler.c
字号:
} parse_inline_string(temp, sibxml); octstr_destroy(temp); return 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(attr->name); if (attr->children != NULL) value = create_octstr_from_node(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;}/* * checks whether a si attribute value is an URL or some other kind of value. * Returns 1 for an URL and 0 otherwise. */static int url(int hex){ switch ((unsigned char) hex) { case 0x0b: /* href */ case 0x0c: case 0x0e: /* href http://, href https:// */ case 0x0d: case 0x0f: /* href http://www., href https://www. */ return 1; } return 0;}/* * checks whether a si attribute value is an action attribute or some other * kind of value. * Returns 1 for an action attribute and 0 otherwise. */static int action(int hex){ switch ((unsigned char) hex) { case 0x05: case 0x06: /* action signal-none, action signal-low */ case 0x07: case 0x08: /* action signal-medium, action signal-high */ case 0x09: /* action delete */ return 1; } return 0;}/* * checks whether a si attribute value is an OSI date or some other kind of * value. * Returns 1 for an action attribute and 0 otherwise. */static int date(int hex){ switch ((unsigned char) hex) { case 0x0a: case 0x10: /* created, si-expires */ return 1; } return 0;}/* * Tokenises an OSI date. Procedure is defined in si, chapter 9.2.2. Validate * OSI date as specified in 9.2.1.1. Returns NULL when error, a tokenised date * string otherwise. */static Octstr *tokenize_date(Octstr *date){ Octstr *date_token; long j; size_t i, date_len; unsigned char c; if (!parse_date(date)) { return NULL; } date_token = octstr_create(""); octstr_append_char(date_token, WBXML_OPAQUE); i = 0; j = 0; date_len = octstr_len(date); while (i < date_len) { c = octstr_get_char(date, i); if (c != 'T' && c != 'Z' && c != '-' && c != ':') { if (isdigit(c)) { octstr_set_bits(date_token, 4*j + 8, 4, c & 0x0f); ++j; } else { octstr_destroy(date_token); return NULL; } } ++i; } octstr_drop_trailing_zeros(&date_token); flag_date_length(&date_token); return date_token;}static void octstr_drop_trailing_zeros(Octstr **date_token){ while (1) { if (octstr_get_char(*date_token, octstr_len(*date_token) - 1) == '\0') octstr_delete(*date_token, octstr_len(*date_token) - 1, 1); else return; }}static void flag_date_length(Octstr **token){ Octstr *lenos; lenos = octstr_format("%c", octstr_len(*token) - 1); octstr_insert(*token, lenos, 1); octstr_destroy(lenos);}/* * The recursive parsing function for the parsing tree. Function checks the * type of the node, calls for the right parse function for the type, then * calls itself for the first child of the current node if there's one and * after that calls itself for the next child on the list. */static int parse_node(xmlNodePtr node, simple_binary_t **sibxml){ int status = 0; /* Call for the parser function of the node type. */ switch (node->type) { case XML_ELEMENT_NODE: status = parse_element(node, sibxml); break; case XML_TEXT_NODE: status = parse_text(node, sibxml); break; case XML_CDATA_SECTION_NODE: status = parse_cdata(node, sibxml); break; case XML_COMMENT_NODE: case XML_PI_NODE: /* Comments and PIs are ignored. */ break; /* * XML has also many other node types, these are not needed with * SI. Therefore they are assumed to be an error. */ default: error(0, "SI compiler: Unknown XML node in the SI source."); return -1; 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, sibxml) == -1) return -1; break; case 1: if (node->children != NULL) if (parse_node(node->children, sibxml) == -1) return -1; parse_end(sibxml); break; case -1: /* Something went wrong in the parsing. */ return -1; default: warning(0,"SI compiler: undefined return value in a parse function."); return -1; break; } if (node->next != NULL) if (parse_node(node->next, sibxml) == -1) return -1; return 0;}/* * Cdata section parsing function. Output this "as it is" */static int parse_cdata(xmlNodePtr node, simple_binary_t **sibxml){ int ret = 0; Octstr *temp; temp = create_octstr_from_node(node); parse_octet_string(temp, sibxml); octstr_destroy(temp); return ret;}/* * In the case of SI documents, only attribute values to be tokenized are * parts of urls (see si, chapter 9.3.3). The caller romoves the start of an * url. Check whether we can find parts in the value. If not, parse value a an * inline string, otherwise parse parts before and after tokenizable parts as * inline strings. */void parse_url_value(Octstr *value, simple_binary_t **sibxml){ size_t i; long pos; Octstr *urlos, *first_part, *last_part; size_t first_part_len; i = 0; first_part_len = 0; first_part = NULL; last_part = NULL; while (i < NUMBER_OF_URL_VALUES) { pos = octstr_search(value, urlos = octstr_imm(si_URL_values[i].name), 0); if (pos >= 0) { first_part = octstr_duplicate(value); octstr_delete(first_part, pos, octstr_len(first_part) - pos); first_part_len = octstr_len(first_part); parse_inline_string(first_part, sibxml); output_char(si_URL_values[i].token, sibxml); last_part = octstr_duplicate(value); octstr_delete(last_part, 0, first_part_len + octstr_len(urlos)); parse_inline_string(last_part, sibxml); octstr_destroy(first_part); octstr_destroy(last_part); break; } octstr_destroy(urlos); ++i; } if (pos < 0) parse_inline_string(value, sibxml); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -