📄 wbxml_encoder.c
字号:
*/static WBXMLError wbxml_encode_tag(WBXMLEncoder *encoder, WBXMLTreeNode *node, WB_BOOL has_content){ const WBXMLTagEntry *tag = NULL; WB_UTINY token = 0x00, page = 0x00; if (node->name->type == WBXML_VALUE_TOKEN) { token = node->name->u.token->wbxmlToken; page = node->name->u.token->wbxmlCodePage; /* Current Tag */ encoder->current_tag = node->name->u.token; } else { /* Search tag in Tags Table */ if ((tag = wbxml_tables_get_tag_from_xml(encoder->lang, wbxml_tag_get_xml_name(node->name))) != NULL) { token = tag->wbxmlToken; page = tag->wbxmlCodePage; /* Current Tag */ encoder->current_tag = tag; } else encoder->current_tag = NULL; } /* Check if this element has content */ if (has_content) token |= WBXML_TOKEN_WITH_CONTENT; /* Check if this element has attributes */ /** @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) */) token |= WBXML_TOKEN_WITH_ATTRS; /* Encode Token */ if ((token & WBXML_TOKEN_MASK) == 0x00) return wbxml_encode_tag_literal(encoder, (WB_UTINY *) wbxml_tag_get_xml_name(node->name), token); else return wbxml_encode_tag_token(encoder, token, page);}/** * @brief Encode a WBXML Literal Token * @param encoder The WBXML Encoder * @param tag The literal tag to encode * @param mask The WBXML Mask for this tag * @return WBXML_OK if encoding is OK, an error code otherwise * @note stag = (literalTag index) * literalTag = LITERAL | LITERAL_A | LITERAL_C | LITERAL_AC * index = mb_u_int32 */static WBXMLError wbxml_encode_tag_literal(WBXMLEncoder *encoder, WB_UTINY *tag, WB_UTINY mask){#if defined( WBXML_ENCODER_USE_STRTBL ) WBXMLStringTableElement *elt = NULL; WBXMLBuffer *buff = NULL; WB_ULONG index = 0; WB_BOOL added = FALSE; /* If String Table generation is disabled, we can't generate this Literal Tag */ if (!encoder->use_strtbl) return WBXML_ERROR_STRTBL_DISABLED; /* Add tag in String Table */ if (((buff = wbxml_buffer_create(tag, WBXML_STRLEN(tag), WBXML_STRLEN(tag))) == NULL) || ((elt = wbxml_strtbl_element_create(buff, FALSE)) == NULL) || (!wbxml_strtbl_add_element(encoder, elt, &index, &added))) { wbxml_strtbl_element_destroy(elt); wbxml_buffer_destroy(buff); return WBXML_ERROR_NOT_ENOUGH_MEMORY; } /* If already exists in String Table: clean-up */ if (!added) wbxml_strtbl_element_destroy(elt); /* Encode literalTag index */ if ((!wbxml_buffer_append_char(encoder->output, (WB_UTINY) (WBXML_LITERAL | mask))) || (!wbxml_buffer_append_mb_uint_32(encoder->output, index))) { return WBXML_ERROR_ENCODER_APPEND_DATA; } return WBXML_OK;#else /* No String Table Support */ return WBXML_ERROR_STRTBL_DISABLED;#endif /* WBXML_ENCODER_USE_STRTBL */}/** * @brief Encode a WBXML Tag Token * @param encoder The WBXML Encoder * @param token The WBXML Tag Token to encode * @param page The WBXML CodePage for this Token * @return WBXML_OK if encoding is OK, an error code otherwise * @note element = ([switchPage] stag) * switchPage = SWITCH_PAGE pageindex * stag = TAG * pageindex = u_int8 */static WBXMLError wbxml_encode_tag_token(WBXMLEncoder *encoder, WB_UTINY token, WB_UTINY page){ /* Switch Page if needed */ if (encoder->tagCodePage != page) { if ((!wbxml_buffer_append_char(encoder->output, WBXML_SWITCH_PAGE)) || (!wbxml_buffer_append_char(encoder->output, page))) { return WBXML_ERROR_ENCODER_APPEND_DATA; } encoder->tagCodePage = page; } /* Add Token */ if (!wbxml_buffer_append_char(encoder->output, token)) return WBXML_ERROR_ENCODER_APPEND_DATA; return WBXML_OK;}/** * @brief Encode a WBXML Attribute * @param encoder [in] The WBXML Encoder * @param attribute [in] The Attribute to encode * @return WBXML_OK if encoding is OK, an error code otherwise * @note attribute = attrStart *attrValue */static WBXMLError wbxml_encode_attr(WBXMLEncoder *encoder, WBXMLAttribute *attribute){ WB_UTINY *value = NULL; WBXMLError ret = WBXML_OK; /* Encode Attribute Start */ if ((ret = wbxml_encode_attr_start(encoder, attribute, &value)) != WBXML_OK) return ret; /* Encode Attribute Value */ if (value != NULL) { if ((ret = wbxml_encode_value_element_buffer(encoder, value, WBXML_VALUE_ELEMENT_CTX_ATTR)) != WBXML_OK) return ret; } /* Reset Current Attribute */ encoder->current_attr = NULL; return WBXML_OK;}/** * @brief Encode a WBXML Attribute Start * @param encoder [in] The WBXML Encoder * @param attribute [in] The Attribute * @param value [out] Pointer to the value to encode * @return WBXML_OK if encoding is OK, an error code otherwise * @note The 'value' result correspond to the value there is still to encode * For example, in Wireless-Village, to encode: * xmlns="http://www.wireless-village.org/CSP1.1" * We first encode: * xmlns="http://www.wireless-village.org/CSP (start token: 0x05) * Then: * "1.1" as an inline string */static WBXMLError wbxml_encode_attr_start(WBXMLEncoder *encoder, WBXMLAttribute *attribute, WB_UTINY **value){ const WBXMLAttrEntry *attr = NULL; WB_UTINY *value_left = NULL; WB_UTINY token = 0x00, page = 0x00; *value = wbxml_buffer_get_cstr(attribute->value); if (attribute->name->type == WBXML_VALUE_TOKEN) { /* We already have Token / Page pair for this Attribute Start */ token = attribute->name->u.token->wbxmlToken; page = attribute->name->u.token->wbxmlCodePage; /* Current Attribute */ encoder->current_attr = attribute->name->u.token; /* If there is a Start Value associated to the Attribute Name token... */ if (attribute->name->u.token->xmlValue != NULL) { /* ... Check that we have it at start of full Attribute Value */ if (WBXML_STRNCMP(wbxml_buffer_get_cstr(attribute->value), attribute->name->u.token->xmlValue, WBXML_STRLEN(attribute->name->u.token->xmlValue)) == 0) { /* Check if you have still a part in the Attribute Value to encode */ if (wbxml_buffer_len(attribute->value) > WBXML_STRLEN(attribute->name->u.token->xmlValue)) { /* There is still a part in the Value to encode */ *value = wbxml_buffer_get_cstr(attribute->value) + WBXML_STRLEN(attribute->name->u.token->xmlValue); } else *value = NULL; } else { /** @todo Should we stop everything and generate an error ? */ WBXML_WARNING((WBXML_ENCODER, "wbxml_encode_attr_start() => Attribute Value doesn't match Attribute Token")); /* Current Attribute */ encoder->current_attr = NULL; /* Encode Attribute Literal */ return wbxml_encode_attr_start_literal(encoder, wbxml_attribute_get_xml_name(attribute)); } } /* Encode Attribute Token */ return wbxml_encode_attr_token(encoder, token, page); } else { /* Search in Attribute table */ if ((attr = wbxml_tables_get_attr_from_xml(encoder->lang, (WB_UTINY *)attribute->name->u.token->xmlName, wbxml_buffer_get_cstr(attribute->value), &value_left)) != NULL) { token = attr->wbxmlToken; page = attr->wbxmlCodePage; /* Current Attribute */ encoder->current_attr = attr; /* If there is still a part in Attribute Value to encode */ *value = value_left; /* Encode Attribute Token */ return wbxml_encode_attr_token(encoder, token, page); } else { /* Current Attribute */ encoder->current_attr = NULL; /* Encode Attribute Literal */ return wbxml_encode_attr_start_literal(encoder, wbxml_attribute_get_xml_name(attribute)); } }}/** * @brief Encode a WBXML Attribute Value * @param encoder The WBXML Encoder * @param buffer The Value Element Buffer to encode * @param ctx Value Element Context (Attribute Value or Content) * @return WBXML_OK if encoding is OK, an error code otherwise * @note attrStart = *attrValue * attrValue = string | extension | entity | opaque * * AND: element = *content * content = string | extension | entity | opaque */static WBXMLError wbxml_encode_value_element_buffer(WBXMLEncoder *encoder, WB_UTINY *buffer, WBXMLValueElementCtx ctx){ WBXMLList *lresult = NULL; WBXMLBuffer *buff = NULL; WBXMLValueElement *elt = NULL, *new_elt = NULL; WB_ULONG i = 0, j = 0, index = 0; WB_UTINY *the_buffer = buffer; WBXMLError ret = WBXML_OK;#if defined( WBXML_ENCODER_USE_STRTBL ) WBXMLStringTableElement *strtbl_elt = NULL;#endif /* WBXML_ENCODER_USE_STRTBL */ if ((buffer == NULL) || (*buffer == '\0')) return WBXML_OK; /********************************************************* * Encoder Language Specific Attribute Values */ if (ctx == WBXML_VALUE_ELEMENT_CTX_ATTR) { switch (encoder->lang->langID) {#if defined( WBXML_SUPPORT_SI ) case WBXML_LANG_SI10: /* SI 1.0: Encode date for 'created' and 'si-expires' attributes */ if ((encoder->current_attr->wbxmlCodePage == 0x00) && ((encoder->current_attr->wbxmlToken == 0x0a) || (encoder->current_attr->wbxmlToken == 0x10))) { return wbxml_encode_datetime(encoder, buffer); } break;#endif /* WBXML_SUPPORT_SI */#if defined( WBXML_SUPPORT_EMN ) case WBXML_LANG_EMN10: /* EMN 1.0: Encode date for 'timestamp' attribute */ if ((encoder->current_attr->wbxmlCodePage == 0x00) && (encoder->current_attr->wbxmlToken == 0x05)) { return wbxml_encode_datetime(encoder, buffer); } break;#endif /* WBXML_SUPPORT_EMN */ default: break; } } /********************************************************* * Encoder Language Specific Content Text Values */ /* If this is a Text Content (not in a CDATA section) */ if ((ctx == WBXML_VALUE_ELEMENT_CTX_CONTENT) && (!encoder->in_cdata)) {#if defined( WBXML_SUPPORT_WV ) /* If this is a Wireless-Village 1.1 / 1.2 document */ if ((encoder->lang->langID == WBXML_LANG_WV_CSP11) || (encoder->lang->langID == WBXML_LANG_WV_CSP12)) { /* Here we try to encode Specific WV Content. If this buffer is not a WV Data Type buffer, or * if it can't be FULLY encoded as an Extension Token, then this function returns WBXML_NOT_ENCODED. * If so, the buffer will be encoded as String latter. */ if ((ret = wbxml_encode_wv_content(encoder, buffer)) != WBXML_NOT_ENCODED) return ret; }#endif /* WBXML_SUPPORT_WV */#if defined( WBXML_SUPPORT_DRMREL ) /* If this is a DRMREL 1.0 document */ if (encoder->lang->langID == WBXML_LANG_DRMREL10) { /* Here we try to encode Specific DRMREL Content. If this buffer is not a DRMREL Data Type buffer * this function returns WBXML_NOT_ENCODED. * If so, the buffer will be encoded as String latter. */ if ((ret = wbxml_encode_drmrel_content(encoder, buffer)) != WBXML_NOT_ENCODED) return ret; }#endif /* WBXML_SUPPORT_DRMREL */#if defined( WBXML_SUPPORT_SYNCML ) /* If this is a SyncML document ? */ if ((encoder->lang->langID == WBXML_LANG_SYNCML_SYNCML10) || (encoder->lang->langID == WBXML_LANG_SYNCML_SYNCML11)) { /** @todo We must check too if we are in a <Type> */ /* Change text in <Type> from "application/vnd.syncml-devinf+xml" to "application/vnd.syncml-devinf+wbxml" */ if (WBXML_STRCASECMP(buffer, "application/vnd.syncml-devinf+xml") == 0) { the_buffer = (WB_UTINY*) "application/vnd.syncml-devinf+wbxml"; } }#endif /* WBXML_SUPPORT_SYNCML */ } /********************************************************* * @todo Search first for simple cases ! */ /********************************************************* * We search the list of Value Elements that represents * this Value buffer */ /* Create Result List */ if ((lresult = wbxml_list_create()) == NULL) return WBXML_ERROR_NOT_ENOUGH_MEMORY; /* Create primary Buffer */ if ((buff = wbxml_buffer_create_from_cstr(the_buffer)) == NULL) { wbxml_list_destroy(lresult, NULL); return WBXML_ERROR_NOT_ENOUGH_MEMORY; } /* Create Value Element for this buffer */ if ((elt = wbxml_value_element_create()) == NULL) { wbxml_buffer_destroy(buff); wbxml_list_destroy(lresult, NULL); return WBXML_ERROR_NOT_ENOUGH_MEMORY; } elt->type = WBXML_VALUE_ELEMENT_STRING; elt->u.str = buff; /* Appen
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -