📄 wbxml_parser.c
字号:
wbxml_buffer_destroy(tmp_value); tmp_value = NULL; } if ((wbxml_buffer_len(attr_value) > 0) && (attr_name->type == WBXML_VALUE_TOKEN)) { /* Handle Language Specific Attribute Values */ switch (parser->langTable->langID) { #if defined( WBXML_SUPPORT_SI ) case WBXML_LANG_SI10: /* SI 1.0: Decode date for 'created' and 'si-expires' attributes */ if ((attr_name->u.token->wbxmlCodePage == 0x00) && ((attr_name->u.token->wbxmlToken == 0x0a) || (attr_name->u.token->wbxmlToken == 0x10))) { if ((ret = decode_datetime(attr_value)) != WBXML_OK) { wbxml_attribute_name_destroy(attr_name); wbxml_buffer_destroy(attr_value); return ret; } } break; #endif /* WBXML_SUPPORT_SI */ #if defined( WBXML_SUPPORT_EMN ) case WBXML_LANG_EMN10: /* EMN 1.0: Decode date for 'timestamp' attribute */ if ((attr_name->u.token->wbxmlCodePage == 0x00) && (attr_name->u.token->wbxmlToken == 0x05)) { if ((ret = decode_datetime(attr_value)) != WBXML_OK) { wbxml_attribute_name_destroy(attr_name); wbxml_buffer_destroy(attr_value); return ret; } } break; #endif /* WBXML_SUPPORT_EMN */ default: break; } } /* Append NULL char to attr value */ if (wbxml_buffer_len(attr_value) > 0) { if (!wbxml_buffer_append_char(attr_value, '\0')) { wbxml_attribute_name_destroy(attr_name); wbxml_buffer_destroy(attr_value); return WBXML_ERROR_NOT_ENOUGH_MEMORY; } } if ((*attr = wbxml_attribute_create()) == NULL) { wbxml_attribute_name_destroy(attr_name); wbxml_buffer_destroy(attr_value); return WBXML_ERROR_NOT_ENOUGH_MEMORY; } (*attr)->name = attr_name; (*attr)->value = attr_value; return WBXML_OK;}/** * @brief Parse WBXML content * @param parser The WBXML Parser * @param result Resulting parsed content, if content is not an Element * @return WBXML_OK if parsing is OK, an error code otherwise * @note content = element | string | extension | entity | pi | opaque */static WBXMLError parse_content(WBXMLParser *parser, WBXMLBuffer **result){ WB_UTINY cur_byte; WBXMLError ret = WBXML_OK; /* Debug */ if (!wbxml_buffer_get_char(parser->wbxml, parser->pos, &cur_byte)) return WBXML_ERROR_END_OF_BUFFER; WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing content: '0x%X'", parser->pos, cur_byte)); /* extension */ if (is_extension(parser)) return parse_extension(parser, WBXML_TAG_TOKEN, result); /* entity */ if (is_token(parser, WBXML_ENTITY)) return parse_entity(parser, result); /* string */ if (is_string(parser)) return parse_string(parser, result); /* opaque */ if (is_token(parser, WBXML_OPAQUE)) { if ((ret = parse_opaque(parser, result)) != WBXML_OK) return ret; return decode_opaque_content(parser, result); } /* pi */ if (is_token(parser, WBXML_PI)) return parse_pi(parser); /** * @note Non standard behaviour because of a Nokia 6600 bug * that generate switch pages in wrong places. * * Thanks to Balaji Alasyam for finding this bug. * * Example : 02 9F 53 6A 00 6D 6C 71 C3 03 31 2E 31 01 72 C3 0A 53 79 6E * 63 4D 4C 2F 31 2E 31 01 65 C3 01 34 01 5B C3 01 31 01 6E 57 * C3 31 68 74 74 70 3A 2F 2F 32 31 30 2E 32 31 34 2E 31 36 31 * 2E 31 37 32 3A 38 30 38 30 2F 74 65 73 74 2F 53 79 6E 63 4D * 4C 3F 75 73 65 72 3D 62 61 6C 75 01 01 67 57 C3 14 49 4D 45 * 49 3A 33 35 31 35 34 36 30 30 35 33 39 34 31 39 39 01 01 5A * 00 01 4C C3 05 31 30 30 30 30 01 00 00 01 01 6B 46 4B C3 ... * ^^^^^ */ /* switchPage */ if ( is_token(parser, WBXML_SWITCH_PAGE) ) return parse_switch_page(parser, WBXML_TAG_TOKEN); /** @note We have recurrency here ! */ return parse_element(parser);}/** * @brief Parse WBXML string * @param parser [in] The WBXML Parsertatic * @param result [out] The resulting parsed string * @return WBXML_OK if parsing is OK, an error code otherwise * @note string = inline | tableref */static WBXMLError parse_string(WBXMLParser *parser, WBXMLBuffer **result){ WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing string", parser->pos)); if (is_token(parser, WBXML_STR_I)) return parse_inline(parser, result); if (is_token(parser, WBXML_STR_T)) return parse_tableref(parser, result); return WBXML_ERROR_STRING_EXPECTED;}/** * @brief Parse WBXML extension * @param parser The WBXML Parser * @param code_space The token code space * @param result Resulting parsed extension * @return WBXML_OK if parsing is OK, an error code otherwise * @note extension = [switchPage] (( EXT_I termstr ) | ( EXT_T index ) | EXT) * @note 5.8.4.2 - The effect of a switchPage preceding an extension will depend upon where the extension appears. * If switchPage appears in content, it will change the tag code page. Is switchPage appears in * an attribute list, it will change the attribute code page. * @note Extensions tokens are explained in WML Specifications (WAP-191-WML-20000219-a.pdf - 14.1.1 & 14.3) * @warning The resulting ext paramater MUST be freed by caller ! */static WBXMLError parse_extension(WBXMLParser *parser, WBXMLTokenType code_space, WBXMLBuffer **result){ WB_UTINY *ext = NULL; WB_ULONG len = 0; WBXMLError ret = WBXML_OK; WB_UTINY token = 0;#if ( defined ( WBXML_SUPPORT_WML ) || defined ( WBXML_SUPPORT_WTA ) ) WB_UTINY var_begin[3] = "$(", var_end[2] = ")", escape[8] = ":escape", unesc[7] = ":unesc", noesc[7] = ":noesc"; WBXMLBuffer *var_value = NULL; WB_ULONG index = 0;#endif /* WBXML_SUPPORT_WML || WBXML_SUPPORT_WTA */ #if defined ( WBXML_SUPPORT_WV ) WB_ULONG ext_value = 0; WB_UTINY tab_index = 0;#endif /* WBXML_SUPPORT_WV */ WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing extension", parser->pos)); /* Parse switchPage */ if (is_token(parser, WBXML_SWITCH_PAGE)) { if ((ret = parse_switch_page(parser, code_space)) != WBXML_OK) { return ret; } } /* Get Extension Token */ if ((ret = parse_uint8(parser, &token)) != WBXML_OK) { return ret; } /* Language specific treatment */ switch (parser->langTable->langID) {#if defined( WBXML_SUPPORT_WML ) case WBXML_LANG_WML10: case WBXML_LANG_WML11: case WBXML_LANG_WML12: case WBXML_LANG_WML13:#endif /* WBXML_SUPPORT_WML */ #if defined( WBXML_SUPPORT_WTA ) case WBXML_LANG_WTAWML12:#endif /* WBXML_SUPPORT_WTA */ #if ( defined( WBXML_SUPPORT_WML ) || defined( WBXML_SUPPORT_WTA ) ) /***************************** * WML Variable Substitution */ switch (token) { case WBXML_EXT_0: case WBXML_EXT_1: case WBXML_EXT_2: WBXML_WARNING((WBXML_PARSER, "This extension token is reserved for futur use (ignoring)")); return WBXML_OK; case WBXML_EXT_I_0: case WBXML_EXT_I_1: case WBXML_EXT_I_2: /* Inline variable */ if ((ret = parse_termstr(parser, &var_value)) != WBXML_OK) { WBXML_ERROR((WBXML_PARSER, "Bad Inline Extension")); return ret; } break; case WBXML_EXT_T_0: case WBXML_EXT_T_1: case WBXML_EXT_T_2: /* Index in String Table */ if ((ret = parse_mb_uint32(parser, &index)) != WBXML_OK) { return ret; } if ((ret = get_strtbl_reference(parser, index, &var_value)) != WBXML_OK) { WBXML_ERROR((WBXML_PARSER, "Bad Extension reference in string table")); return ret; } break; default: return WBXML_ERROR_UNKNOWN_EXTENSION_TOKEN; } /* Build Variable */ ext = (WB_UTINY*) wbxml_malloc(WBXML_STRLEN(var_begin) + wbxml_buffer_len(var_value) + WBXML_STRLEN(escape) + WBXML_STRLEN(var_end) + 1); if (ext == NULL) { return WBXML_ERROR_NOT_ENOUGH_MEMORY; } /* Generate "$(" */ memcpy(ext + len, var_begin, WBXML_STRLEN(var_begin)); len += WBXML_STRLEN(var_begin); /* Generate 'variable' */ memcpy(ext + len, wbxml_buffer_get_cstr(var_value), wbxml_buffer_len(var_value)); len += wbxml_buffer_len(var_value); /* Destroy 'variable' */ wbxml_buffer_destroy(var_value); switch (token) { case WBXML_EXT_I_0: case WBXML_EXT_T_0: /* Generate ":escape" */ memcpy(ext + len, escape, WBXML_STRLEN(escape)); len += WBXML_STRLEN(escape); break; case WBXML_EXT_I_1: case WBXML_EXT_T_1: /* Generate ":unesc" */ memcpy(ext + len, unesc, WBXML_STRLEN(unesc)); len += WBXML_STRLEN(unesc); break; case WBXML_EXT_I_2: case WBXML_EXT_T_2: /* Generate ":noesc" */ memcpy(ext + len, noesc, WBXML_STRLEN(noesc)); len += WBXML_STRLEN(noesc); break; default: return WBXML_ERROR_UNKNOWN_EXTENSION_TOKEN; } /* Generate ")" */ memcpy(ext + len, var_end, WBXML_STRLEN(var_end)); len += WBXML_STRLEN(var_end); break;#endif /* WBXML_SUPPORT_WML || WBXML_SUPPORT_WTA */#if defined( WBXML_SUPPORT_WV ) case WBXML_LANG_WV_CSP11: case WBXML_LANG_WV_CSP12: /********************************** * Wireless Village extension */ if (token != WBXML_EXT_T_0) { WBXML_ERROR((WBXML_PARSER, "Only EXT_T_0 extensions authorized with Wireless Village CSP")); return WBXML_OK; } /* Get Extension Value Token */ if ((ret = parse_mb_uint32(parser, &ext_value)) != WBXML_OK) { return ret; } /* Search Token in Extension Value Table */ if (parser->langTable == NULL) { return WBXML_ERROR_LANG_TABLE_UNDEFINED; } if (parser->langTable->extValueTable == NULL) { return WBXML_ERROR_EXT_VALUE_TABLE_UNDEFINED; } tab_index = 0; while ((parser->langTable->extValueTable[tab_index].xmlName != NULL) && (parser->langTable->extValueTable[tab_index].wbxmlToken != ext_value) ) { tab_index++; } if (parser->langTable->extValueTable[tab_index].xmlName == NULL) {#if WBXML_PARSER_BEST_EFFORT ext = (WB_UTINY *) wbxml_strdup((const WB_TINY*) WBXML_PARSER_UNKNOWN_STRING); len = WBXML_STRLEN(WBXML_PARSER_UNKNOWN_STRING); return WBXML_OK;#else return WBXML_ERROR_UNKNOWN_EXTENSION_VALUE;#endif /* WBXML_PARSER_BEST_EFFORT */ } ext = (WB_UTINY *) wbxml_strdup((const WB_TINY*) parser->langTable->extValueTable[tab_index].xmlName); len = WBXML_STRLEN(parser->langTable->extValueTable[tab_index].xmlName); break;#endif /* WBXML_SUPPORT_WV */ default: WBXML_ERROR((WBXML_PARSER, "Extension tokens not allowed with this Document !")); } /* Set result */ if (ext == NULL) { *result = NULL; } else { if ((*result = wbxml_buffer_create(ext, len, len)) == NULL) { return WBXML_ERROR_NOT_ENOUGH_MEMORY; } /** @todo Replace this local var by the direct creation of the result Buffer */ wbxml_free(ext); } return WBXML_OK;}/** * @brief Parse WBXML entity * @param parser The WBXML Parser * @param result The resulting parsed entity * @return WBXML_OK if parsing is OK, an error code otherwise * @note entity = ENTITY entcode * @note http://www.w3.org/TR/wbxml/ : * "The character entity token (ENTITY) encodes a numeric character entity. This has the same semantics * as an XML numeric character entity (eg,  ). The mb_u_int32 refers to a character in the UCS-4 * character encoding. All entities in the source XML document must be represented using either a string * token (eg, STR_I or the ENTITY token." * @warning The resulting entity paramater MUST be freed by caller ! */static WBXMLError parse_entity(WBXMLParser *parser, WBXMLBuffer **result){ WB_TINY entity[10]; WB_ULONG code = 0; WBXMLError ret = WBXML_OK; WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing entity", parser->pos));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -