📄 wbxml_encoder.c
字号:
/**************************** * Common Functions */#if 0/** * @brief Convert a char to UCS-4 * @param ch [in] The character to convert * @param result [out] The UCS-4 code * @return TRUE if convertion succeeded, FALSE otherwise */static WB_BOOL convert_char_to_ucs4(WB_UTINY ch, WB_ULONG *result){ /** @todo convert_char_to_ucs4() */ return FALSE;}#endif /* 0 *//** * @brief Duplicate a WBXML Encoder * @param encoder [in] The WBXML Encoder to Duplicate * @return The duplicated WBXML Encoder, or NULL if error * @note Only options (parameters) fields are duplicated, others are reset */static WBXMLEncoder *encoder_duplicate(WBXMLEncoder *encoder){ WBXMLEncoder *result = NULL; if ((result = wbxml_encoder_create()) == NULL) return NULL; result->ignore_empty_text = encoder->ignore_empty_text; result->remove_text_blanks = encoder->remove_text_blanks; result->output_type = encoder->output_type; result->xml_gen_type = encoder->xml_gen_type; result->indent_delta = encoder->indent_delta; result->indent = encoder->indent;#if defined( WBXML_ENCODER_USE_STRTBL ) result->use_strtbl = encoder->use_strtbl;#endif /* WBXML_ENCODER_USE_STRTBL */ /* Do NOT generate XML Header */ result->xml_encode_header = FALSE; result->wbxml_version = encoder->wbxml_version; return result;}static WBXMLError encoder_encode_tree(WBXMLEncoder *encoder){ WBXMLError ret = WBXML_OK; /* Check Parameters */ if ((encoder == NULL) || (encoder->tree == NULL) || ((encoder->lang == NULL) && (encoder->tree->lang == NULL)) || ((encoder->output_type != WBXML_ENCODER_OUTPUT_XML) && (encoder->output_type != WBXML_ENCODER_OUTPUT_WBXML))) { return WBXML_ERROR_BAD_PARAMETER; } if (encoder->lang == NULL) encoder->lang = encoder->tree->lang; /* Choose Output Charset */ if (encoder->output_charset == WBXML_CHARSET_UNKNOWN) { /* User has not choosen the Output Charset Encoding */ if (encoder->tree->orig_charset != WBXML_CHARSET_UNKNOWN) { /* Use the original Charset Encoding found when we have parsed the original document */ encoder->output_charset = encoder->tree->orig_charset; } else { /* Use default charset */ encoder->output_charset = WBXML_ENCODER_XML_DEFAULT_CHARSET; } } /* Init Output Buffer */ if (!encoder_init_output(encoder)) { wbxml_encoder_destroy(encoder); return WBXML_ERROR_NOT_ENOUGH_MEMORY; } #if defined( WBXML_ENCODER_USE_STRTBL ) if (encoder->output_type == WBXML_ENCODER_OUTPUT_WBXML) { /* Choose if we will use String Table */ switch (encoder->lang->langID) { #if defined( WBXML_SUPPORT_WV ) /* Wireless-Village CSP 1.1 / 1.2: content can be tokenized, so we mustn't interfere with String Table stuff */ case WBXML_LANG_WV_CSP11: case WBXML_LANG_WV_CSP12: encoder->use_strtbl = FALSE; break; #endif /* WBXML_SUPPORT_WV */ #if defined( WBXML_SUPPORT_OTA_SETTINGS ) /* Nokia Ericsson OTA Settings : string tables are not supported */ case WBXML_LANG_OTA_SETTINGS: encoder->use_strtbl = FALSE; break; #endif /* WBXML_SUPPORT_OTA_SETTINGS */ default: /* Use Default Value */ break; } /* Init String Table */ if (encoder->use_strtbl) { /** * @bug If 'output_charset' is different from UTF-8, the string table initialization * also is erroneous !!! */ if ((ret = wbxml_strtbl_initialize(encoder, encoder->tree->root)) != WBXML_OK) return ret; } } #endif /* WBXML_ENCODER_USE_STRTBL */ /* Let's begin WBXML Tree Parsing */ return parse_node(encoder, encoder->tree->root, TRUE);}static WB_BOOL encoder_init_output(WBXMLEncoder *encoder){ WB_ULONG malloc_block = 0; if (encoder == NULL) return FALSE; /* Check if output already inited */ if (encoder->output != NULL) return TRUE; /* Get malloc block */ if (encoder->output_type == WBXML_ENCODER_OUTPUT_WBXML) malloc_block = WBXML_ENCODER_WBXML_DOC_MALLOC_BLOCK; else malloc_block = WBXML_ENCODER_XML_DOC_MALLOC_BLOCK; /* Init Output Buffer */ encoder->output = wbxml_buffer_create("", 0, malloc_block); if (encoder->output == NULL) return FALSE; return TRUE;}/********************************* * WBXML Tree Parsing Functions *//** * @brief Parse an XML Node * @param encoder The WBXML Encoder * @param node The node to parse * @param enc_end If node is an element, do we encoded its end ? * @return WBXML_OK if parsing is OK, an error code otherwise * @note We have recurrency in this function */static WBXMLError parse_node(WBXMLEncoder *encoder, WBXMLTreeNode *node, WB_BOOL enc_end){ WBXMLError ret = WBXML_OK; /* Parse this node */ switch (node->type) { case WBXML_TREE_ELEMENT_NODE: ret = parse_element(encoder, node, node->children != NULL); break; case WBXML_TREE_TEXT_NODE: ret = parse_text(encoder, node); break; case WBXML_TREE_CDATA_NODE: ret = parse_cdata(encoder, node); break; case WBXML_TREE_PI_NODE: ret = parse_pi(encoder, node); break; case WBXML_TREE_TREE_NODE: ret = parse_tree(encoder, node); break; default: return WBXML_ERROR_XML_NODE_NOT_ALLOWED; } if (ret != WBXML_OK) return ret; /* Check if node has children */ if (node->children != NULL) { /* Parse Child */ if ((ret = parse_node(encoder, node->children, TRUE)) != WBXML_OK) return ret; } /* Handle end of Element or CDATA section */ switch (node->type) { case WBXML_TREE_ELEMENT_NODE: if (enc_end) { switch(encoder->output_type) { case WBXML_ENCODER_OUTPUT_XML:#if defined( WBXML_ENCODER_XML_GEN_EMPTY_ELT ) if (node->children != NULL) {#endif /* WBXML_ENCODER_XML_GEN_EMPTY_ELT */ /* Encode end tag */ if ((ret = xml_encode_end_tag(encoder, node)) != WBXML_OK) return ret; WBXML_DEBUG((WBXML_ENCODER, "End Element"));#if defined( WBXML_ENCODER_XML_GEN_EMPTY_ELT ) }#endif /* WBXML_ENCODER_XML_GEN_EMPTY_ELT */ break; case WBXML_ENCODER_OUTPUT_WBXML: if (node->children != NULL) { /* Add a WBXML End tag */ if ((ret = wbxml_encode_end(encoder)) != WBXML_OK) return ret; WBXML_DEBUG((WBXML_ENCODER, "End Element")); } break; default: /* hu ? */ break; } /* switch */ } /* if */ break; case WBXML_TREE_CDATA_NODE: /* End of CDATA section */ encoder->in_cdata = FALSE; WBXML_DEBUG((WBXML_ENCODER, "End CDATA")); switch(encoder->output_type) { case WBXML_ENCODER_OUTPUT_XML: /* Encode XML "End of CDATA section" */ if ((ret = xml_encode_end_cdata(encoder)) != WBXML_OK) return ret; break; case WBXML_ENCODER_OUTPUT_WBXML: if (encoder->cdata == NULL) { /* Must never happen */ return WBXML_ERROR_INTERNAL; } /* Encode CDATA Buffer into Opaque */ if (wbxml_buffer_len(encoder->cdata) > 0) { if ((ret = wbxml_encode_opaque(encoder, encoder->cdata)) != WBXML_OK) return ret; } /* Reset CDATA Buffer */ wbxml_buffer_destroy(encoder->cdata); encoder->cdata = NULL; break; default: /* hu ? */ break; } /* switch */ break; default: /* NOP */ break; } /* Reset Current Tag */ encoder->current_tag = NULL; /* Parse next node */ if (node->next != NULL) return parse_node(encoder, node->next, TRUE); else return WBXML_OK;}/** * @brief Parse an XML Element * @param encoder The WBXML Encoder * @param node The element to parse * @param has_content Does the element has content ? * @return WBXML_OK if parsing is OK, an error code otherwise */static WBXMLError parse_element(WBXMLEncoder *encoder, WBXMLTreeNode *node, WB_BOOL has_content){ WB_ULONG i = 0; WBXMLError ret = WBXML_OK; WBXML_DEBUG((WBXML_ENCODER, "Element: <%s>", wbxml_tag_get_xml_name(node->name))); /* Encode: Element Name */ switch (encoder->output_type) { case WBXML_ENCODER_OUTPUT_WBXML: if ((ret = wbxml_encode_tag(encoder, node, has_content)) != WBXML_OK) return ret; break; case WBXML_ENCODER_OUTPUT_XML: if ((ret = xml_encode_tag(encoder, node)) != WBXML_OK) return ret; break; default: return WBXML_ERROR_INTERNAL; } /** @todo Check handling of Namespaces */ /** @todo For Canonical XML Output: Attributes MUST be sorted */ /* Parse: Attributes List */ if (node->attrs != NULL) { for (i = 0; i < wbxml_list_len(node->attrs); i++) { /* Parse: Attribute */ if ((ret = parse_attribute(encoder, wbxml_list_get(node->attrs, i))) != WBXML_OK) return ret; } } /* Encode: End of attributes */ switch (encoder->output_type) { case WBXML_ENCODER_OUTPUT_WBXML: /** @todo Check if the attributes will really be tokenized. There can be ignored attributes, and so NO attribute * tokenized at all. */ if ((node->attrs != NULL) && (encoder->lang->attrTable != NULL) /** @todo Fast patch for SyncML (change this) */) { if ((ret = wbxml_encode_end(encoder)) != WBXML_OK) return ret; WBXML_DEBUG((WBXML_ENCODER, "End Attributes")); } break; case WBXML_ENCODER_OUTPUT_XML: /* Encode end of attributes */ if ((ret = xml_encode_end_attrs(encoder, node)) != WBXML_OK) return ret; WBXML_DEBUG((WBXML_ENCODER, "End Attributes")); break; default: return WBXML_ERROR_INTERNAL; } return WBXML_OK;}/** * @brief Parse an Element End * @param encoder The WBXML Encoder * @param node The element to parse * @param has_content Does the element has content ? * @return WBXML_OK if parsing is OK, an error code otherwise */static WBXMLError parse_element_end(WBXMLEncoder *encoder, WBXMLTreeNode *node, WB_BOOL has_content){ WBXMLError ret = WBXML_OK; if (encoder->output_type == WBXML_ENCODER_OUTPUT_XML) {#if defined( WBXML_ENCODER_XML_GEN_EMPTY_ELT ) if (has_content) {#endif /* WBXML_ENCODER_XML_GEN_EMPTY_ELT */ /* Encode end tag */ ret = xml_encode_end_tag(encoder, node); WBXML_DEBUG((WBXML_ENCODER, "End Element"));#if defined( WBXML_ENCODER_XML_GEN_EMPTY_ELT ) }#endif /* WBXML_ENCODER_XML_GEN_EMPTY_ELT */ } else if (encoder->output_type == WBXML_ENCODER_OUTPUT_WBXML) { if (has_content) { /* Add a WBXML End tag */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -