📄 wbxml_parser.c
字号:
&attr_name, &start_value)) != WBXML_OK) { return ret; } if (start_value != NULL ) { /* Create a buffer from attribute start value */ attr_value = wbxml_buffer_create(start_value, WBXML_STRLEN(start_value), WBXML_PARSER_ATTR_VALUE_MALLOC_BLOCK); } else { /* Create an empty buffer */ attr_value = wbxml_buffer_create(NULL, 0, WBXML_PARSER_ATTR_VALUE_MALLOC_BLOCK); } if (attr_value == NULL) { /* Memory error */ wbxml_attribute_name_destroy(attr_name); return WBXML_ERROR_NOT_ENOUGH_MEMORY; } /* Parse *attrValue */ while (!is_token(parser, WBXML_END)) { /* Parse attrValue */ if ((ret = parse_attr_value(parser, &tmp_value)) != WBXML_OK) { wbxml_attribute_name_destroy(attr_name); wbxml_buffer_destroy(attr_value); return ret; } /* Append to main attribute value buffer */ if (!wbxml_buffer_append(attr_value, tmp_value)) { wbxml_attribute_name_destroy(attr_name); wbxml_buffer_destroy(attr_value); wbxml_buffer_destroy(tmp_value); return WBXML_ERROR_NOT_ENOUGH_MEMORY; } wbxml_buffer_destroy(tmp_value); tmp_value = NULL; } /* Skip END */ parser->pos++; /* 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; } } /* Callback WBXMLProcessingInstructionHandler */ if ((parser->content_hdl != NULL) && (parser->content_hdl->pi_clb != NULL)) { parser->content_hdl->pi_clb(parser->user_data, wbxml_attribute_name_get_xml_name(attr_name), wbxml_buffer_get_cstr(attr_value)); } wbxml_attribute_name_destroy(attr_name); wbxml_buffer_destroy(attr_value); return WBXML_OK;}/** * @brief Parse WBXML element * @param parser The WBXML Parser * @return WBXML_OK if parsing is OK, an error code otherwise * @note element = ([switchPage] stag) [ 1*attribute END ] [ *content END ] */static WBXMLError parse_element(WBXMLParser *parser){ WBXMLTag *element = NULL; WBXMLAttribute *attr = NULL; WBXMLAttribute **attrs = NULL; WBXMLBuffer *content = NULL; WB_ULONG attrs_nb = 0; WBXMLError ret = WBXML_OK; WB_UTINY tag = 0; WB_BOOL is_empty = FALSE; WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing element", parser->pos)); if (is_token(parser, WBXML_SWITCH_PAGE)) { if ((ret = parse_switch_page(parser, WBXML_TAG_TOKEN)) != WBXML_OK) { return ret; } } /* Parse Tag */ if ((ret = parse_stag(parser, &tag, &element)) != WBXML_OK ) { return ret; } /* Set Current Tag */ if (element->type == WBXML_VALUE_TOKEN) { parser->current_tag = element->u.token; } /* Parse Attributes */ if (tag & WBXML_TOKEN_WITH_ATTRS) { WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing attributes", parser->pos)); /* There must be at least one attribute */ do { /* Parse attribute */ if ((ret = parse_attribute(parser, &attr)) != WBXML_OK) { wbxml_tag_destroy(element); free_attrs_table(attrs); return ret; } /* Append this attribute in WBXMLAttribute **attrs table */ attrs_nb++; if ((attrs = wbxml_realloc(attrs, (attrs_nb + 1) * sizeof(*attrs))) == NULL) { /* Clean-up */ wbxml_tag_destroy(element); wbxml_attribute_destroy(attr); free_attrs_table(attrs); return WBXML_ERROR_NOT_ENOUGH_MEMORY; } attrs[(attrs_nb - 1)] = attr; attrs[attrs_nb] = NULL; } while ( !is_token(parser, WBXML_END) ); /* Skip END */ parser->pos++; } /* Is it an empty element ? */ is_empty = (WB_BOOL) !(tag & WBXML_TOKEN_WITH_CONTENT); /* Callback WBXMLStartElementHandler */ if ((parser->content_hdl != NULL) && (parser->content_hdl->start_element_clb != NULL)) { parser->content_hdl->start_element_clb(parser->user_data, element, attrs, is_empty); } /* Free Attributes */ free_attrs_table(attrs); /* Parse *content */ if (!is_empty) { /* There can be NO content */ while (!is_token(parser, WBXML_END)) { /* Parse content */ if ((ret = parse_content(parser, &content)) != WBXML_OK) { wbxml_tag_destroy(element); return ret; } /* Callback WBXMLCharactersHandler if content is not NULL */ if ((content != NULL) && (wbxml_buffer_len(content) != 0) && (parser->content_hdl != NULL) && (parser->content_hdl->characters_clb != NULL)) { parser->content_hdl->characters_clb(parser->user_data, wbxml_buffer_get_cstr(content), 0, wbxml_buffer_len(content)); } /* Free content */ wbxml_buffer_destroy(content); content = NULL; } WBXML_DEBUG((WBXML_PARSER, "(%d) End of Element", parser->pos)); /* Skip END */ parser->pos++; } /* Callback WBXMLEndElementHandler */ if ((parser->content_hdl != NULL) && (parser->content_hdl->end_element_clb != NULL)) { parser->content_hdl->end_element_clb(parser->user_data, element, is_empty); } /* Free Tag */ wbxml_tag_destroy(element); /* Reset Current Tag */ parser->current_tag = NULL; return WBXML_OK;}/** * @brief Free a (WBXMLAttribute *) table * @param attrs The table to ree */static void free_attrs_table(WBXMLAttribute **attrs){ WB_LONG i = 0; if (attrs != NULL) { while (attrs[i] != NULL) { /* Free attribute */ wbxml_attribute_destroy(attrs[i++]); } wbxml_free(attrs); }}/** * @brief Parse WBXML switchPage * @param parser The WBXML Parser * @param code_space The token code space * @return WBXML_OK if parsing is OK, an error code otherwise * @note switchPage = SWITCH_PAGE pageindex */static WBXMLError parse_switch_page(WBXMLParser *parser, WBXMLTokenType code_space){ WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing switchPage", parser->pos)); if ((WB_UTINY) parser->version < (WB_UTINY) WBXML_VERSION_12) WBXML_WARNING((WBXML_PARSER, "No Switch Page mecanism possible in WBXML < %s", WBXML_VERSION_TEXT_12)); /* Skip SWITCH_PAGE token */ parser->pos++; /* Change Code Page in correct Code Space */ if (code_space == WBXML_TAG_TOKEN) return parse_uint8(parser, &parser->tagCodePage); else if (code_space == WBXML_ATTR_TOKEN) return parse_uint8(parser, &parser->attrCodePage); else return WBXML_ERROR_INTERNAL;}/** * @brief Parse WBXML stag * @param parser The WBXML Parser * @param tag The parsed tag token * @param element The parsed element corresponding to token * @return WBXML_OK if parsing is OK, an error code otherwise * @note stag = TAG | (literalTag index) */static WBXMLError parse_stag(WBXMLParser *parser, WB_UTINY *tag, WBXMLTag **element){ WBXMLBuffer *name = NULL; WBXMLError ret = WBXML_OK; WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing stag", parser->pos)); if (is_literal(parser)) { /* Parse '(literalTag index)' */ if ((ret = parse_literal(parser, tag, &name)) != WBXML_OK) { return ret; } /* Create Element Tag */ if ((*element = wbxml_tag_create_literal(wbxml_buffer_get_cstr(name))) == NULL) { ret = WBXML_ERROR_NOT_ENOUGH_MEMORY; } wbxml_buffer_destroy(name); return ret; } /* Parse 'TAG' */ return parse_tag(parser, tag, element);}/** * @brief Parse WBXML Application Token (tag) * @param parser The WBXML Parser * @param tag The parsed token tag * @param element The parsed element (the text element corresponding to token) * @return WBXML_OK if parsing is OK, an error code otherwise */static WBXMLError parse_tag(WBXMLParser *parser, WB_UTINY *tag, WBXMLTag **element){ WB_ULONG index = 0; WB_UTINY token; WBXMLError ret = WBXML_OK; /* Parse UINT8 */ ret = parse_uint8(parser, tag); if (ret != WBXML_OK) return ret; /* Remove ATTR and CONTENT bits */ token = (WB_UTINY) (*tag & WBXML_TOKEN_MASK); /* Search tag in Tags Table */ if (parser->langTable == NULL) return WBXML_ERROR_LANG_TABLE_UNDEFINED; if (parser->langTable->tagTable == NULL) return WBXML_ERROR_TAG_TABLE_UNDEFINED; while ((parser->langTable->tagTable[index].xmlName != NULL) && ((parser->langTable->tagTable[index].wbxmlToken != token) || (parser->langTable->tagTable[index].wbxmlCodePage != parser->tagCodePage))) { index++; } if (parser->langTable->tagTable[index].xmlName == NULL) {#if WBXML_PARSER_BEST_EFFORT /* Create "unknown" Tag Element */ if ((*element = wbxml_tag_create_literal(WBXML_PARSER_UNKNOWN_STRING)) == NULL) return WBXML_ERROR_NOT_ENOUGH_MEMORY; return WBXML_OK;#else return WBXML_ERROR_UNKNOWN_TAG;#endif /* WBXML_PARSER_BEST_EFFORT */ } if ((*element = wbxml_tag_create(WBXML_VALUE_TOKEN)) == NULL) return WBXML_ERROR_NOT_ENOUGH_MEMORY; (*element)->u.token = &(parser->langTable->tagTable[index]); WBXML_DEBUG((WBXML_PARSER, "(%d) Token: 0x%X", parser->pos - 1, token)); return WBXML_OK;}/** * @brief Parse WBXML attribute * @param parser The WBXML Parser * @param attr The resulting attribute parsed * @return WBXML_OK if parsing is OK, an error code otherwise * @note attribute = attrStart *attrValue * @warning The attr_value parameter MUST be freed by caller */static WBXMLError parse_attribute(WBXMLParser *parser, WBXMLAttribute **attr){ WBXMLAttributeName *attr_name = NULL; const WB_UTINY *start_value = NULL; WBXMLBuffer *attr_value = NULL; WBXMLBuffer *tmp_value = NULL; WBXMLError ret = WBXML_OK; WBXML_DEBUG((WBXML_PARSER, "(%d) Parsing attribute", parser->pos)); /* Parse attrStart */ if ((ret = parse_attr_start(parser, &attr_name, &start_value)) != WBXML_OK) { return ret; } if ( start_value != NULL ) { /* Create a buffer from attribute start value */ attr_value = wbxml_buffer_create(start_value, WBXML_STRLEN(start_value), WBXML_PARSER_ATTR_VALUE_MALLOC_BLOCK); } else { /* Create an empty buffer */ attr_value = wbxml_buffer_create(NULL, 0, WBXML_PARSER_ATTR_VALUE_MALLOC_BLOCK); } if (attr_value == NULL) { /* Memory error */ wbxml_attribute_name_destroy(attr_name); return WBXML_ERROR_NOT_ENOUGH_MEMORY; } /* Construct Attribute Value */ while (is_attr_value(parser)) { /* Parse attrValue */ if ((ret = parse_attr_value(parser, &tmp_value)) != WBXML_OK) { wbxml_attribute_name_destroy(attr_name); wbxml_buffer_destroy(attr_value); return ret; } if (!wbxml_buffer_append(attr_value, tmp_value)) { wbxml_attribute_name_destroy(attr_name); wbxml_buffer_destroy(attr_value); wbxml_buffer_destroy(tmp_value); return WBXML_ERROR_NOT_ENOUGH_MEMORY; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -