00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00048 #include <stdlib.h>
00049 #include <string.h>
00050 #include <ctype.h>
00051
00052 #include "wbxml.h"
00053
00054
00062
00063
00064
00065
00066
00067 #define WBXML_HEADER_MAX_LEN 16
00068
00069
00070 #define WBXML_ENCODER_XML_DOC_MALLOC_BLOCK 5000
00071 #define WBXML_ENCODER_WBXML_DOC_MALLOC_BLOCK 1000
00072
00073 #define WBXML_ENCODER_XML_HEADER_MALLOC_BLOCK 250
00074 #define WBXML_ENCODER_WBXML_HEADER_MALLOC_BLOCK WBXML_HEADER_MAX_LEN
00075
00076
00077 #define WBXML_ENCODER_DEFAULT_CHARSET 0x6a
00078
00079
00080 #define WBXML_STR_END '\0'
00081
00082
00083 #define WBXML_ENCODER_STRING_TABLE_MIN 3
00084
00088 typedef enum WBXMLEncoderOutputType_e {
00089 WBXML_ENCODER_OUTPUT_WBXML = 0,
00090 WBXML_ENCODER_OUTPUT_XML
00091 } WBXMLEncoderOutputType;
00092
00098 struct WBXMLEncoder_s {
00099 WBXMLTree *tree;
00100 WBXMLBuffer *output;
00101 const WBXMLTagEntry *current_tag;
00102 const WBXMLAttrEntry *current_attr;
00103 WB_UTINY tagCodePage;
00104 WB_UTINY attrCodePage;
00105 WB_BOOL ignore_empty_text;
00106 WB_BOOL remove_text_blanks;
00107 WBXMLEncoderOutputType output_type;
00108 WBXMLEncoderXMLGenType xml_gen_type;
00109 WB_UTINY indent_delta;
00110 WB_UTINY indent;
00111 WB_BOOL in_content;
00112 #if defined( WBXML_ENCODER_USE_STRTBL )
00113 WBXMLList *strstbl;
00114 WB_ULONG strstbl_len;
00115 WB_BOOL use_strtbl;
00116 #endif
00117 WB_BOOL xml_encode_header;
00118 WBXMLVersion wbxml_version;
00119 };
00120
00121 #if defined( WBXML_ENCODER_USE_STRTBL )
00122
00125 typedef struct WBXMLStringTableElement_t {
00126 WBXMLBuffer *string;
00127 WB_ULONG offset;
00128 WB_ULONG count;
00129 WB_BOOL stat;
00130 } WBXMLStringTableElement;
00131 #endif
00132
00136 typedef enum WBXMLValueElementCtx_e {
00137 WBXML_VALUE_ELEMENT_CTX_CONTENT = 0,
00138 WBXML_VALUE_ELEMENT_CTX_ATTR
00139 } WBXMLValueElementCtx;
00140
00144 typedef enum WBXMLValueElementType_e {
00145 WBXML_VALUE_ELEMENT_STRING = 0,
00146 WBXML_VALUE_ELEMENT_EXTENSION,
00147 WBXML_VALUE_ELEMENT_OPAQUE,
00148 WBXML_VALUE_ELEMENT_ATTR_TOKEN
00149 #if defined( WBXML_ENCODER_USE_STRTBL )
00150 , WBXML_VALUE_ELEMENT_TABLEREF
00151 #endif
00152 } WBXMLValueElementType;
00153
00157 typedef struct WBXMLValueElement_t {
00158 WBXMLValueElementType type;
00159 union {
00160 WBXMLBuffer *str;
00161 const WBXMLExtValueEntry *ext;
00162 WBXMLBuffer *buff;
00163 const WBXMLAttrValueEntry *attr;
00164 #if defined( WBXML_ENCODER_USE_STRTBL )
00165 WB_ULONG index;
00166 #endif
00167 } u;
00168 } WBXMLValueElement;
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 static WB_BOOL convert_char_to_ucs4(WB_UTINY ch, WB_ULONG *result);
00180 static WBXMLEncoder *wbxml_encoder_duplicate(WBXMLEncoder *encoder);
00181
00182
00183
00184
00185
00186
00187 static WBXMLError parse_node(WBXMLEncoder *encoder, WBXMLTreeNode *node);
00188 static WBXMLError parse_element(WBXMLEncoder *encoder, WBXMLTreeNode *node);
00189 static WBXMLError parse_attribute(WBXMLEncoder *encoder, WBXMLAttribute *attribute);
00190 static WBXMLError parse_text(WBXMLEncoder *encoder, WBXMLTreeNode *node);
00191 static WBXMLError parse_cdata(WBXMLEncoder *encoder, WBXMLTreeNode *node);
00192 static WBXMLError parse_pi(WBXMLEncoder *encoder, WBXMLTreeNode *node);
00193 static WBXMLError parse_tree(WBXMLEncoder *encoder, WBXMLTreeNode *node);
00194
00195
00196
00197
00198
00199
00200
00201 static WBXMLError wbxml_build_result(WBXMLEncoder *encoder, WB_UTINY **wbxml, WB_ULONG *wbxml_len);
00202
00203
00204 static WBXMLError wbxml_encode_end(WBXMLEncoder *encoder);
00205
00206 static WBXMLError wbxml_encode_tag(WBXMLEncoder *encoer, WBXMLTreeNode *node);
00207 static WBXMLError wbxml_encode_tag_literal(WBXMLEncoder *encoder, WB_UTINY *tag, WB_UTINY mask);
00208 static WBXMLError wbxml_encode_tag_token(WBXMLEncoder *encoder, WB_UTINY token, WB_UTINY page);
00209
00210 static WBXMLError wbxml_encode_attr(WBXMLEncoder *encoder, WBXMLAttribute *attribute);
00211 static WBXMLError wbxml_encode_attr_start(WBXMLEncoder *encoder, WBXMLAttribute *attribute, WB_UTINY **value);
00212 static WBXMLError wbxml_encode_value_element_buffer(WBXMLEncoder *encoder, WB_UTINY *value, WBXMLValueElementCtx ctx);
00213 static WBXMLError wbxml_encode_value_element_list(WBXMLEncoder *encoder, WBXMLList *list);
00214 static WBXMLError wbxml_encode_attr_start_literal(WBXMLEncoder *encoder, const WB_UTINY *attr);
00215 static WBXMLError wbxml_encode_attr_token(WBXMLEncoder *encoder, WB_UTINY token, WB_UTINY page);
00216
00217 static WBXMLError wbxml_encode_inline_string(WBXMLEncoder *encoder, WBXMLBuffer *str);
00218 static WBXMLError wbxml_encode_inline_integer_extension_token(WBXMLEncoder *encoder, WB_UTINY ext, WB_UTINY value);
00219 static WBXMLError wbxml_encode_entity(WBXMLEncoder *encoder, WB_ULONG value);
00220 static WBXMLError wbxml_encode_opaque(WBXMLEncoder *encoder, WBXMLBuffer *buff);
00221 #if defined( WBXML_ENCODER_USE_STRTBL )
00222 static WBXMLError wbxml_encode_tableref(WBXMLEncoder *encoder, WB_ULONG offset);
00223 #endif
00224
00225 static WBXMLValueElement *wbxml_value_element_create(void);
00226 static void wbxml_value_element_destroy(WBXMLValueElement *elt);
00227 static void wbxml_value_element_destroy_item(void *elt);
00228
00229 static WBXMLError wbxml_encode_tree(WBXMLEncoder *encoder, WBXMLTree *tree);
00230
00231 #if ( defined( WBXML_SUPPORT_SI ) || defined( WBXML_SUPPORT_EMN ) )
00232 static WBXMLError wbxml_encode_datetime(WBXMLEncoder *encoder, WB_UTINY *buffer);
00233 #endif
00234
00235 #if defined( WBXML_SUPPORT_WV )
00236 static WBXMLError wbxml_encode_wv_content(WBXMLEncoder *encoder, WB_UTINY *buffer);
00237 static WBXMLError wbxml_encode_wv_integer(WBXMLEncoder *encoder, WB_UTINY *buffer);
00238 static WBXMLError wbxml_encode_wv_datetime(WBXMLEncoder *encoder, WB_UTINY *buffer);
00239 #endif
00240
00241 #if defined( WBXML_SUPPORT_DRMREL )
00242 static WBXMLError wbxml_encode_drmrel_content(WBXMLEncoder *encoder, WB_UTINY *buffer);
00243 #endif
00244
00245 #if defined( WBXML_ENCODER_USE_STRTBL )
00246
00247 static WBXMLStringTableElement *wbxml_strtbl_element_create(WBXMLBuffer *string, WB_BOOL is_stat);
00248 static void wbxml_strtbl_element_destroy(WBXMLStringTableElement *element);
00249 static void wbxml_strtbl_element_destroy_item(void *element);
00250
00251 static WBXMLError wbxml_strtbl_initialize(WBXMLEncoder *encoder, WBXMLTreeNode *root);
00252 static void wbxml_strtbl_collect_strings(WBXMLEncoder *encoder, WBXMLTreeNode *node, WBXMLList *strings);
00253 static WBXMLError wbxml_strtbl_collect_words(WBXMLList *elements, WBXMLList **result);
00254 static void wbxml_strtbl_construct(WB_UTINY *buff, WBXMLList *strstbl);
00255 static WBXMLError wbxml_strtbl_check_references(WBXMLEncoder *encoder, WBXMLList **strings, WBXMLList **one_ref, WB_BOOL stat_buff);
00256 static WB_BOOL wbxml_strtbl_add_element(WBXMLEncoder *encoder, WBXMLStringTableElement *elt, WB_ULONG *index, WB_BOOL *added);
00257 #endif
00258
00259
00260
00261
00262
00263
00265 #define WBXML_ENCODER_XML_NEW_LINE ((WB_UTINY *)"\n")
00266
00267
00268 #define WBXML_ENCODER_XML_HEADER "<?xml version=\"1.0\"?>"
00269 #define WBXML_ENCODER_XML_DOCTYPE "<!DOCTYPE "
00270 #define WBXML_ENCODER_XML_PUBLIC " PUBLIC \""
00271 #define WBXML_ENCODER_XML_DTD "\" \""
00272 #define WBXML_ENCODER_XML_END_DTD "\">"
00273
00274
00275 const WB_UTINY xml_lt[5] = "<";
00276 const WB_UTINY xml_gt[5] = ">";
00277 const WB_UTINY xml_amp[6] = "&";
00278 const WB_UTINY xml_quot[7] = """;
00279 const WB_UTINY xml_slashr[6] = " ";
00280 const WB_UTINY xml_slashn[6] = " ";
00281 const WB_UTINY xml_tab[5] = "	";
00283
00284 static WBXMLError xml_build_result(WBXMLEncoder *encoder, WB_UTINY **xml);
00285 static WB_BOOL xml_fill_header(WBXMLEncoder *encoder, WBXMLBuffer *header);
00286
00287
00288 static WBXMLError xml_encode_tag(WBXMLEncoder *encoer, WBXMLTreeNode *node);
00289 static WBXMLError xml_encode_end_tag(WBXMLEncoder *encoder, WBXMLTreeNode *node);
00290
00291 static WBXMLError xml_encode_attr(WBXMLEncoder *encoder, WBXMLAttribute *attribute);
00292 static WBXMLError xml_encode_end_attrs(WBXMLEncoder *encoder);
00293
00294 static WBXMLError xml_encode_text(WBXMLEncoder *encoder, WBXMLBuffer *str);
00295 static WB_BOOL xml_encode_new_line(WBXMLBuffer *buff);
00296 static WB_BOOL xml_normalize(WBXMLBuffer *buff);
00297
00298 static WBXMLError xml_encode_tree(WBXMLEncoder *encoder, WBXMLTree *tree);
00299
00300
00301
00302
00303
00304
00305
00306
00307 WBXML_DECLARE(WBXMLEncoder *) wbxml_encoder_create_real(void)
00308 {
00309 WBXMLEncoder *encoder = NULL;
00310
00311 encoder = (WBXMLEncoder *) wbxml_malloc(sizeof(WBXMLEncoder));
00312 if (encoder == NULL) {
00313 return NULL;
00314 }
00315
00316 #if defined( WBXML_ENCODER_USE_STRTBL )
00317 if ((encoder->strstbl = wbxml_list_create()) == NULL) {
00318 wbxml_free(encoder);
00319 return NULL;
00320 }
00321 encoder->use_strtbl = TRUE;
00322 encoder->strstbl_len = 0;
00323 #endif
00324
00325 encoder->tree = NULL;
00326 encoder->output = NULL;
00327
00328 encoder->current_tag = NULL;
00329 encoder->current_attr = NULL;
00330
00331 encoder->tagCodePage = 0;
00332 encoder->attrCodePage = 0;
00333
00334 encoder->ignore_empty_text = FALSE;
00335 encoder->remove_text_blanks = FALSE;
00336
00337 encoder->output_type = WBXML_ENCODER_OUTPUT_WBXML;
00338 encoder->xml_gen_type = WBXML_ENCODER_XML_GEN_COMPACT;
00339
00340 encoder->indent_delta = 1;
00341 encoder->indent = 0;
00342 encoder->in_content = FALSE;
00343
00344 encoder->xml_encode_header = TRUE;
00345
00346
00347 encoder->wbxml_version = WBXML_VERSION_13;
00348
00349 return encoder;
00350 }
00351
00352
00353 WBXML_DECLARE(void) wbxml_encoder_destroy(WBXMLEncoder *encoder)
00354 {
00355 if (encoder == NULL)
00356 return;
00357
00358 wbxml_buffer_destroy(encoder->output);
00359
00360 #if defined( WBXML_ENCODER_USE_STRTBL )
00361 wbxml_list_destroy(encoder->strstbl, wbxml_strtbl_element_destroy_item);
00362 #endif
00363
00364 wbxml_free(encoder);
00365 }
00366
00367
00368
00369
00370 WBXML_DECLARE(void) wbxml_encoder_set_ignore_empty_text(WBXMLEncoder *encoder, WB_BOOL set_ignore)
00371 {
00372 if (encoder == NULL)
00373 return;
00374
00375 encoder->ignore_empty_text = set_ignore;
00376 }
00377
00378
00379 WBXML_DECLARE(void) wbxml_encoder_set_remove_text_blanks(WBXMLEncoder *encoder, WB_BOOL set_remove)
00380 {
00381 if (encoder == NULL)
00382 return;
00383
00384 encoder->remove_text_blanks = set_remove;
00385 }
00386
00387
00388
00389
00390 WBXML_DECLARE(void) wbxml_encoder_set_use_strtbl(WBXMLEncoder *encoder, WB_BOOL use_strtbl)
00391 {
00392 #if defined( WBXML_ENCODER_USE_STRTBL )
00393 if (encoder == NULL)
00394 return;
00395
00396 encoder->use_strtbl = use_strtbl;
00397 #endif
00398 }
00399
00400
00401 WBXML_DECLARE(void) wbxml_encoder_set_wbxml_version(WBXMLEncoder *encoder, WBXMLVersion version)
00402 {
00403 if (encoder == NULL)
00404 return;
00405
00406 if (version != WBXML_VERSION_UNKNOWN)
00407 encoder->wbxml_version = version;
00408 }
00409
00410
00411
00412
00413 WBXML_DECLARE(void) wbxml_encoder_set_xml_gen_type(WBXMLEncoder *encoder, WBXMLEncoderXMLGenType gen_type)
00414 {
00415 if (encoder == NULL)
00416 return;
00417
00418 encoder->xml_gen_type = gen_type;
00419 }
00420
00421
00422 WBXML_DECLARE(void) wbxml_encoder_set_indent(WBXMLEncoder *encoder, WB_UTINY indent)
00423 {
00424 if (encoder == NULL)
00425 return;
00426
00427 encoder->indent_delta = indent;
00428 }
00429
00430
00431
00432
00433 WBXML_DECLARE(void) wbxml_encoder_set_tree(WBXMLEncoder *encoder, WBXMLTree *tree)
00434 {
00435 if (encoder == NULL)
00436 return;
00437
00438 encoder->tree = tree;
00439 }
00440
00441
00442 WBXML_DECLARE(WBXMLError) wbxml_encoder_encode_to_wbxml(WBXMLEncoder *encoder, WB_UTINY **wbxml, WB_ULONG *wbxml_len)
00443 {
00444 WBXMLError ret = WBXML_OK;
00445
00446
00447 if ((encoder == NULL) || (encoder->tree == NULL) || (encoder->tree->lang == NULL) || (wbxml == NULL) || (wbxml_len == NULL))
00448 return WBXML_ERROR_BAD_PARAMETER;
00449
00450
00451 encoder->output_type = WBXML_ENCODER_OUTPUT_WBXML;
00452
00453
00454 *wbxml = NULL;
00455 *wbxml_len = 0;
00456
00457
00458 encoder->output = wbxml_buffer_create("", 0, WBXML_ENCODER_WBXML_DOC_MALLOC_BLOCK);
00459 if (encoder->output == NULL) {
00460 wbxml_encoder_destroy(encoder);
00461 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
00462 }
00463
00464 #if defined( WBXML_ENCODER_USE_STRTBL )
00465
00466
00467 switch (encoder->tree->lang->langID)
00468 {
00469 #if defined( WBXML_SUPPORT_WV )
00470
00471 case WBXML_LANG_WV_CSP11:
00472 case WBXML_LANG_WV_CSP12:
00473 encoder->use_strtbl = FALSE;
00474 break;
00475 #endif
00476
00477 default:
00478
00479 break;
00480 }
00481
00482
00483 if (encoder->use_strtbl) {
00484 if ((ret = wbxml_strtbl_initialize(encoder, encoder->tree->root)) != WBXML_OK)
00485 return ret;
00486 }
00487
00488 #endif
00489
00490
00491 if ((ret = parse_node(encoder, encoder->tree->root)) != WBXML_OK)
00492 return ret;
00493
00494
00495 return wbxml_build_result(encoder, wbxml, wbxml_len);
00496 }
00497
00498
00499 WBXML_DECLARE(WBXMLError) wbxml_encoder_encode_to_xml(WBXMLEncoder *encoder, WB_UTINY **xml)
00500 {
00501 WBXMLError ret = WBXML_OK;
00502
00503
00504 if ((encoder == NULL) || (encoder->tree == NULL) || (encoder->tree->lang == NULL) || (xml == NULL))
00505 return WBXML_ERROR_BAD_PARAMETER;
00506
00507
00508 encoder->output_type = WBXML_ENCODER_OUTPUT_XML;
00509
00510
00511 *xml = NULL;
00512
00513
00514 encoder->output = wbxml_buffer_create("", 0, WBXML_ENCODER_XML_DOC_MALLOC_BLOCK);
00515 if (encoder->output == NULL) {
00516 wbxml_encoder_destroy(encoder);
00517 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
00518 }
00519
00520
00521 if ((ret = parse_node(encoder, encoder->tree->root)) != WBXML_OK)
00522 return ret;
00523
00524
00525 return xml_build_result(encoder, xml);
00526 }
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00544 static WB_BOOL convert_char_to_ucs4(WB_UTINY ch, WB_ULONG *result)
00545 {
00548 return FALSE;
00549 }
00550
00551
00558 static WBXMLEncoder *wbxml_encoder_duplicate(WBXMLEncoder *encoder)
00559 {
00560 WBXMLEncoder *result = NULL;
00561
00562 if ((result = wbxml_encoder_create()) == NULL)
00563 return NULL;
00564
00565 result->ignore_empty_text = encoder->ignore_empty_text;
00566 result->remove_text_blanks = encoder->remove_text_blanks;
00567
00568 result->output_type = encoder->output_type;
00569 result->xml_gen_type = encoder->xml_gen_type;
00570
00571 result->indent_delta = encoder->indent_delta;
00572 result->indent = encoder->indent;
00573
00574 result->use_strtbl = encoder->use_strtbl;
00575
00576
00577 result->xml_encode_header = FALSE;
00578
00579 result->wbxml_version = encoder->wbxml_version;
00580
00581 return result;
00582 }
00583
00584
00585
00586
00587
00588
00596 static WBXMLError parse_node(WBXMLEncoder *encoder, WBXMLTreeNode *node)
00597 {
00598 WBXMLError ret = WBXML_OK;
00599
00600
00601 switch (node->type) {
00602 case WBXML_TREE_ELEMENT_NODE:
00603 ret = parse_element(encoder, node);
00604 break;
00605 case WBXML_TREE_TEXT_NODE:
00606 ret = parse_text(encoder, node);
00607 break;
00608 case WBXML_TREE_PI_NODE:
00609 ret = parse_pi(encoder, node);
00610 break;
00611 case WBXML_TREE_TREE_NODE:
00612 ret = parse_tree(encoder, node);
00613 break;
00614 default:
00615 return WBXML_ERROR_XML_NODE_NOT_ALLOWED;
00616 break;
00617 }
00618
00619 if (ret != WBXML_OK)
00620 return ret;
00621
00622
00623 if (node->children != NULL) {
00624
00625 if ((ret = parse_node(encoder, node->children)) != WBXML_OK)
00626 return ret;
00627
00628
00629 if (encoder->output_type == WBXML_ENCODER_OUTPUT_WBXML) {
00630 if ((ret = wbxml_encode_end(encoder)) != WBXML_OK)
00631 return ret;
00632
00633 WBXML_DEBUG((WBXML_ENCODER, "End Element"));
00634 }
00635 }
00636
00637
00638 encoder->current_tag = NULL;
00639
00640
00641 if ((encoder->output_type == WBXML_ENCODER_OUTPUT_XML) &&
00642 (node->type == WBXML_TREE_ELEMENT_NODE))
00643 {
00644 if ((ret = xml_encode_end_tag(encoder, node)) != WBXML_OK)
00645 return ret;
00646
00647 WBXML_DEBUG((WBXML_ENCODER, "End Element"));
00648 }
00649
00650
00651 if (node->next != NULL)
00652 return parse_node(encoder, node->next);
00653 else
00654 return WBXML_OK;
00655 }
00656
00657
00664 static WBXMLError parse_element(WBXMLEncoder *encoder, WBXMLTreeNode *node)
00665 {
00666 WBXMLTreeAttribute *attribute = NULL;
00667 WB_UTINY ret = WBXML_OK;
00668
00669 WBXML_DEBUG((WBXML_ENCODER, "Element: <%s>", wbxml_tag_get_xml_name(node->name)));
00670
00671
00672 switch (encoder->output_type) {
00673 case WBXML_ENCODER_OUTPUT_WBXML:
00674 if ((ret = wbxml_encode_tag(encoder, node)) != WBXML_OK)
00675 return ret;
00676 break;
00677 case WBXML_ENCODER_OUTPUT_XML:
00678 if ((ret = xml_encode_tag(encoder, node)) != WBXML_OK)
00679 return ret;
00680 break;
00681 default:
00682 return WBXML_ERROR_INTERNAL;
00683 }
00684
00689
00690 if ((attribute = node->attrs) != NULL)
00691 {
00692 while (attribute != NULL) {
00693
00694 if ((ret = parse_attribute(encoder, attribute->attr)) != WBXML_OK)
00695 return ret;
00696
00697 attribute = attribute->next;
00698 }
00699 }
00700
00701
00702 switch (encoder->output_type) {
00703 case WBXML_ENCODER_OUTPUT_WBXML:
00707 if ((node->attrs != NULL) && (encoder->tree->lang->attrTable != NULL) ) {
00708 if ((ret = wbxml_encode_end(encoder)) != WBXML_OK)
00709 return ret;
00710 }
00711 break;
00712 case WBXML_ENCODER_OUTPUT_XML:
00713 if ((ret = xml_encode_end_attrs(encoder)) != WBXML_OK)
00714 return ret;
00715 break;
00716 default:
00717 return WBXML_ERROR_INTERNAL;
00718 }
00719
00720 return WBXML_OK;
00721 }
00722
00723
00730 static WBXMLError parse_attribute(WBXMLEncoder *encoder, WBXMLAttribute *attribute)
00731 {
00732 if (encoder->tree->lang == NULL)
00733 return WBXML_ERROR_LANG_TABLE_UNDEFINED;
00734
00735 if (encoder->tree->lang->attrTable == NULL)
00736 return WBXML_OK;
00737
00738
00739 if (attribute->name == NULL)
00740 return WBXML_ERROR_XML_NULL_ATTR_NAME;
00741
00742 WBXML_DEBUG((WBXML_ENCODER, "Attribute: %s = %s", wbxml_attribute_get_xml_name(attribute), wbxml_attribute_get_xml_value(attribute)));
00743
00744
00745 switch (encoder->output_type) {
00746 case WBXML_ENCODER_OUTPUT_WBXML:
00747 return wbxml_encode_attr(encoder, attribute);
00748 case WBXML_ENCODER_OUTPUT_XML:
00749 return xml_encode_attr(encoder, attribute);
00750 default:
00751 return WBXML_ERROR_INTERNAL;
00752 }
00753 }
00754
00755
00762 static WBXMLError parse_text(WBXMLEncoder *encoder, WBXMLTreeNode *node)
00763 {
00764
00765 if (encoder->xml_gen_type != WBXML_ENCODER_XML_GEN_CANONICAL) {
00766
00767 if ((encoder->ignore_empty_text) && (wbxml_buffer_contains_only_whitespaces(node->content)))
00768 return WBXML_OK;
00769
00770
00771 if (encoder->remove_text_blanks)
00772 wbxml_buffer_strip_blanks(node->content);
00773 }
00774
00775
00776 switch (encoder->output_type) {
00777 case WBXML_ENCODER_OUTPUT_WBXML:
00778 return wbxml_encode_value_element_buffer(encoder, wbxml_buffer_get_cstr(node->content), WBXML_VALUE_ELEMENT_CTX_CONTENT);
00779 case WBXML_ENCODER_OUTPUT_XML:
00780 return xml_encode_text(encoder, node->content);
00781 default:
00782 return WBXML_ERROR_INTERNAL;
00783 }
00784
00785 return WBXML_OK;
00786 }
00787
00788
00795 static WBXMLError parse_cdata(WBXMLEncoder *encoder, WBXMLTreeNode *node)
00796 {
00799 return WBXML_ERROR_NOT_IMPLEMENTED;
00800 }
00801
00802
00809 static WBXMLError parse_pi(WBXMLEncoder *encoder, WBXMLTreeNode *node)
00810 {
00813 return WBXML_ERROR_NOT_IMPLEMENTED;
00814 }
00815
00816
00823 static WBXMLError parse_tree(WBXMLEncoder *encoder, WBXMLTreeNode *node)
00824 {
00825 switch (encoder->output_type) {
00826 case WBXML_ENCODER_OUTPUT_WBXML:
00827 return wbxml_encode_tree(encoder, node->tree);
00828 case WBXML_ENCODER_OUTPUT_XML:
00829 return xml_encode_tree(encoder, node->tree);
00830 default:
00831 return WBXML_ERROR_INTERNAL;
00832 }
00833 }
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00853 static WBXMLError wbxml_build_result(WBXMLEncoder *encoder, WB_UTINY **wbxml, WB_ULONG *wbxml_len)
00854 {
00855 WBXMLBuffer *header = NULL, *pid = NULL;
00856 WB_ULONG public_id, public_id_index, strstbl_len = 0;
00857 WB_BOOL pi_in_strtbl = FALSE, added = FALSE;
00858
00859 #if defined( WBXML_ENCODER_USE_STRTBL )
00860 WBXMLStringTableElement *elt = NULL;
00861
00862 strstbl_len = encoder->strstbl_len;
00863 #endif
00864
00865
00866 public_id = encoder->tree->lang->publicID->wbxmlPublicID;
00867
00868
00869 header = wbxml_buffer_create("", 0, WBXML_ENCODER_WBXML_HEADER_MALLOC_BLOCK);
00870 if (header == NULL)
00871 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
00872
00873
00874 if (!wbxml_buffer_append_char(header, (WB_UTINY) encoder->wbxml_version))
00875
00876 {
00877 wbxml_buffer_destroy(header);
00878 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
00879 }
00880
00881
00882
00883 if (public_id == WBXML_PUBLIC_ID_UNKNOWN)
00884 {
00885 if (encoder->tree->lang->publicID->xmlPublicID != NULL)
00886 {
00887 if ((pid = wbxml_buffer_create(encoder->tree->lang->publicID->xmlPublicID,
00888 WBXML_STRLEN(encoder->tree->lang->publicID->xmlPublicID),
00889 WBXML_STRLEN(encoder->tree->lang->publicID->xmlPublicID))) == NULL)
00890 {
00891 wbxml_buffer_destroy(pid);
00892 wbxml_buffer_destroy(header);
00893 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
00894 }
00895
00896 #if defined( WBXML_ENCODER_USE_STRTBL )
00897 if ((elt = wbxml_strtbl_element_create(pid, FALSE)) == NULL)
00898 {
00899 wbxml_buffer_destroy(pid);
00900 wbxml_buffer_destroy(header);
00901 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
00902 }
00903
00904 if (!wbxml_strtbl_add_element(encoder,
00905 elt,
00906 &public_id_index,
00907 &added))
00908 {
00909 wbxml_buffer_destroy(header);
00910 wbxml_strtbl_element_destroy(elt);
00911 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
00912 }
00913
00914 if (!added)
00915 wbxml_strtbl_element_destroy(elt);
00916
00917 strstbl_len = encoder->strstbl_len;
00918 #else
00919
00920 strstbl_len = wbxml_buffer_len(pid) + 1;
00921
00922
00923 public_id_index = 0;
00924 #endif
00925
00926 pi_in_strtbl = TRUE;
00927 }
00928 }
00929
00930
00931 if (pi_in_strtbl) {
00932
00933 if (!wbxml_buffer_append_char(header, 0x00) ||
00934 !wbxml_buffer_append_mb_uint_32(header, public_id_index))
00935 {
00936 wbxml_buffer_destroy(header);
00937 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
00938 }
00939 }
00940 else {
00941
00942 if (!wbxml_buffer_append_mb_uint_32(header, public_id)) {
00943 wbxml_buffer_destroy(header);
00944 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
00945 }
00946 }
00947
00948
00950 if (!wbxml_buffer_append_mb_uint_32(header, WBXML_ENCODER_DEFAULT_CHARSET) ||
00951 !wbxml_buffer_append_mb_uint_32(header, strstbl_len))
00952 {
00953 wbxml_buffer_destroy(header);
00954 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
00955 }
00956
00957
00958 *wbxml_len = wbxml_buffer_len(header) + strstbl_len + wbxml_buffer_len(encoder->output);
00959
00960
00961 *wbxml = (WB_UTINY *) wbxml_malloc(*wbxml_len * sizeof(WB_UTINY));
00962 if (*wbxml == NULL) {
00963 wbxml_buffer_destroy(header);
00964 *wbxml_len = 0;
00965 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
00966 }
00967
00968
00969 memcpy(*wbxml, wbxml_buffer_get_cstr(header), wbxml_buffer_len(header));
00970
00971
00972 #if defined( WBXML_ENCODER_USE_STRTBL )
00973 wbxml_strtbl_construct(*wbxml + wbxml_buffer_len(header), encoder->strstbl);
00974 #else
00975
00976 memcpy(*wbxml + wbxml_buffer_len(header), wbxml_buffer_get_cstr(pid), strstbl_len);
00977
00978 wbxml_buffer_destroy(pid);
00979 #endif
00980
00981
00982 memcpy(*wbxml + wbxml_buffer_len(header) + strstbl_len, wbxml_buffer_get_cstr(encoder->output), wbxml_buffer_len(encoder->output));
00983
00984 wbxml_buffer_destroy(header);
00985
00986 return WBXML_OK;
00987 }
00988
00989
00990
00991
00992
00993
00999 static WBXMLError wbxml_encode_end(WBXMLEncoder *encoder)
01000 {
01001
01002 if (!wbxml_buffer_append_char(encoder->output, WBXML_END))
01003 return WBXML_ERROR_ENCODER_APPEND_DATA;
01004
01005 return WBXML_OK;
01006 }
01007
01008
01015 static WBXMLError wbxml_encode_tag(WBXMLEncoder *encoder, WBXMLTreeNode *node)
01016 {
01017 const WBXMLTagEntry *tag = NULL;
01018 WB_UTINY token = 0x00, page = 0x00;
01019
01020 if (node->name->type == WBXML_VALUE_TOKEN) {
01021 token = node->name->u.token->wbxmlToken;
01022 page = node->name->u.token->wbxmlCodePage;
01023
01024
01025 encoder->current_tag = node->name->u.token;
01026 }
01027 else {
01028
01029 if ((tag = wbxml_tables_get_tag_from_xml(encoder->tree->lang, wbxml_tag_get_xml_name(node->name))) != NULL)
01030 {
01031 token = tag->wbxmlToken;
01032 page = tag->wbxmlCodePage;
01033
01034
01035 encoder->current_tag = tag;
01036 }
01037 else
01038 encoder->current_tag = NULL;
01039 }
01040
01041
01042 if (node->children != NULL)
01043 token |= WBXML_TOKEN_WITH_CONTENT;
01044
01045
01049 if ((node->attrs != NULL) && (encoder->tree->lang->attrTable != NULL) )
01050 token |= WBXML_TOKEN_WITH_ATTRS;
01051
01052
01053 if ((token & WBXML_TOKEN_MASK) == 0x00)
01054 return wbxml_encode_tag_literal(encoder, (WB_UTINY *) wbxml_tag_get_xml_name(node->name), token);
01055 else
01056 return wbxml_encode_tag_token(encoder, token, page);
01057 }
01058
01059
01070 static WBXMLError wbxml_encode_tag_literal(WBXMLEncoder *encoder, WB_UTINY *tag, WB_UTINY mask)
01071 {
01072 #if defined( WBXML_ENCODER_USE_STRTBL )
01073 WBXMLStringTableElement *elt = NULL;
01074 WBXMLBuffer *buff = NULL;
01075 WB_ULONG index = 0;
01076 WB_BOOL added = FALSE;
01077
01078
01079 if (!encoder->use_strtbl)
01080 return WBXML_ERROR_STRTBL_DISABLED;
01081
01082
01083 if (((buff = wbxml_buffer_create(tag, WBXML_STRLEN(tag), WBXML_STRLEN(tag))) == NULL) ||
01084 ((elt = wbxml_strtbl_element_create(buff, FALSE)) == NULL) ||
01085 (!wbxml_strtbl_add_element(encoder, elt, &index, &added)))
01086 {
01087 wbxml_strtbl_element_destroy(elt);
01088 wbxml_buffer_destroy(buff);
01089 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01090 }
01091
01092
01093 if (!added)
01094 wbxml_strtbl_element_destroy(elt);
01095
01096
01097 if ((!wbxml_buffer_append_char(encoder->output, (WB_UTINY) (WBXML_LITERAL | mask))) ||
01098 (!wbxml_buffer_append_mb_uint_32(encoder->output, index)))
01099 {
01100 return WBXML_ERROR_ENCODER_APPEND_DATA;
01101 }
01102
01103 return WBXML_OK;
01104 #else
01105
01106 return WBXML_ERROR_STRTBL_DISABLED;
01107 #endif
01108 }
01109
01110
01122 static WBXMLError wbxml_encode_tag_token(WBXMLEncoder *encoder, WB_UTINY token, WB_UTINY page)
01123 {
01124
01125 if (encoder->tagCodePage != page)
01126 {
01127 if ((!wbxml_buffer_append_char(encoder->output, WBXML_SWITCH_PAGE)) ||
01128 (!wbxml_buffer_append_char(encoder->output, page)))
01129 {
01130 return WBXML_ERROR_ENCODER_APPEND_DATA;
01131 }
01132
01133 encoder->tagCodePage = page;
01134 }
01135
01136
01137 if (!wbxml_buffer_append_char(encoder->output, token))
01138 return WBXML_ERROR_ENCODER_APPEND_DATA;
01139
01140 return WBXML_OK;
01141 }
01142
01143
01151 static WBXMLError wbxml_encode_attr(WBXMLEncoder *encoder, WBXMLAttribute *attribute)
01152 {
01153 WB_UTINY *value = NULL;
01154 WBXMLError ret = WBXML_OK;
01155
01156
01157 if ((ret = wbxml_encode_attr_start(encoder, attribute, &value)) != WBXML_OK)
01158 return ret;
01159
01160
01161 if (value != NULL) {
01162 if ((ret = wbxml_encode_value_element_buffer(encoder, value, WBXML_VALUE_ELEMENT_CTX_ATTR)) != WBXML_OK)
01163 return ret;
01164 }
01165
01166
01167 encoder->current_attr = NULL;
01168
01169 return WBXML_OK;
01170 }
01171
01172
01187 static WBXMLError wbxml_encode_attr_start(WBXMLEncoder *encoder, WBXMLAttribute *attribute, WB_UTINY **value)
01188 {
01189 const WBXMLAttrEntry *attr = NULL;
01190 WB_UTINY *value_left = NULL;
01191 WB_UTINY token = 0x00, page = 0x00;
01192
01193 *value = wbxml_buffer_get_cstr(attribute->value);
01194
01195 if (attribute->name->type == WBXML_VALUE_TOKEN) {
01196
01197 token = attribute->name->u.token->wbxmlToken;
01198 page = attribute->name->u.token->wbxmlCodePage;
01199
01200
01201 encoder->current_attr = attribute->name->u.token;
01202
01203
01204 if (attribute->name->u.token->xmlValue != NULL)
01205 {
01206
01207 if (WBXML_STRNCMP(wbxml_buffer_get_cstr(attribute->value),
01208 attribute->name->u.token->xmlValue,
01209 WBXML_STRLEN(attribute->name->u.token->xmlValue)) == 0)
01210 {
01211
01212 if (wbxml_buffer_len(attribute->value) > WBXML_STRLEN(attribute->name->u.token->xmlValue))
01213 {
01214
01215 *value = wbxml_buffer_get_cstr(attribute->value) + WBXML_STRLEN(attribute->name->u.token->xmlValue);
01216 }
01217 else
01218 *value = NULL;
01219 }
01220 else {
01222 WBXML_WARNING((WBXML_ENCODER, "wbxml_encode_attr_start() => Attribute Value doesn't match Attribute Token"));
01223
01224
01225 encoder->current_attr = NULL;
01226
01227
01228 return wbxml_encode_attr_start_literal(encoder, wbxml_attribute_get_xml_name(attribute));
01229 }
01230 }
01231
01232
01233 return wbxml_encode_attr_token(encoder, token, page);
01234 }
01235 else {
01236
01237 if ((attr = wbxml_tables_get_attr_from_xml(encoder->tree->lang,
01238 (WB_UTINY *)attribute->name->u.token->xmlName,
01239 wbxml_buffer_get_cstr(attribute->value),
01240 &value_left)) != NULL)
01241 {
01242 token = attr->wbxmlToken;
01243 page = attr->wbxmlCodePage;
01244
01245
01246 encoder->current_attr = attr;
01247
01248
01249 *value = value_left;
01250
01251
01252 return wbxml_encode_attr_token(encoder, token, page);
01253 }
01254 else {
01255
01256 encoder->current_attr = NULL;
01257
01258
01259 return wbxml_encode_attr_start_literal(encoder, wbxml_attribute_get_xml_name(attribute));
01260 }
01261 }
01262 }
01263
01264
01277 static WBXMLError wbxml_encode_value_element_buffer(WBXMLEncoder *encoder, WB_UTINY *buffer, WBXMLValueElementCtx ctx)
01278 {
01279 WBXMLList *lresult = NULL;
01280 WBXMLBuffer *buff = NULL;
01281 WBXMLValueElement *elt = NULL, *new_elt = NULL;
01282 WB_ULONG i = 0, j = 0, index = 0;
01283 WB_UTINY *the_buffer = buffer;
01284 WBXMLError ret = WBXML_OK;
01285
01286 #if defined( WBXML_ENCODER_USE_STRTBL )
01287 WBXMLStringTableElement *strtbl_elt = NULL;
01288 #endif
01289
01290 if ((buffer == NULL) || (*buffer == '\0'))
01291 return WBXML_OK;
01292
01293
01294
01295
01296
01297
01298 if (ctx == WBXML_VALUE_ELEMENT_CTX_ATTR) {
01299 switch (encoder->tree->lang->langID) {
01300 #if defined( WBXML_SUPPORT_SI )
01301 case WBXML_LANG_SI10:
01302
01303 if ((encoder->current_attr->wbxmlCodePage == 0x00) &&
01304 ((encoder->current_attr->wbxmlToken == 0x0a) || (encoder->current_attr->wbxmlToken == 0x10)))
01305 {
01306 return wbxml_encode_datetime(encoder, buffer);
01307 }
01308 break;
01309 #endif
01310
01311 #if defined( WBXML_SUPPORT_EMN )
01312 case WBXML_LANG_EMN10:
01313
01314 if ((encoder->current_attr->wbxmlCodePage == 0x00) && (encoder->current_attr->wbxmlToken == 0x05))
01315 {
01316 return wbxml_encode_datetime(encoder, buffer);
01317 }
01318 break;
01319 #endif
01320
01321 default:
01322 break;
01323 }
01324 }
01325
01326
01327
01328
01329
01330
01331
01332 if (ctx == WBXML_VALUE_ELEMENT_CTX_CONTENT)
01333 {
01334 #if defined( WBXML_SUPPORT_WV )
01335
01336 if ((encoder->tree->lang->langID == WBXML_LANG_WV_CSP11) ||
01337 (encoder->tree->lang->langID == WBXML_LANG_WV_CSP12))
01338 {
01339
01340
01341
01342
01343 if ((ret = wbxml_encode_wv_content(encoder, buffer)) != WBXML_NOT_ENCODED)
01344 return ret;
01345 }
01346 #endif
01347
01348 #if defined( WBXML_SUPPORT_DRMREL )
01349
01350 if (encoder->tree->lang->langID == WBXML_LANG_DRMREL10)
01351 {
01352
01353
01354
01355
01356 if ((ret = wbxml_encode_drmrel_content(encoder, buffer)) != WBXML_NOT_ENCODED)
01357 return ret;
01358 }
01359 #endif
01360
01361 #if defined( WBXML_SUPPORT_SYNCML )
01362
01363 if ((encoder->tree->lang->langID == WBXML_LANG_SYNCML_SYNCML10) ||
01364 (encoder->tree->lang->langID == WBXML_LANG_SYNCML_SYNCML11))
01365 {
01368
01369 if (WBXML_STRCASECMP(buffer, "application/vnd.syncml-devinf+xml") == 0) {
01370 the_buffer = (WB_UTINY*) "application/vnd.syncml-devinf+wbxml";
01371 }
01372 }
01373 #endif
01374 }
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388 if ((lresult = wbxml_list_create()) == NULL)
01389 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01390
01391
01392 if ((buff = wbxml_buffer_create_from_cstr(the_buffer)) == NULL) {
01393 wbxml_list_destroy(lresult, NULL);
01394 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01395 }
01396
01397
01398 if ((elt = wbxml_value_element_create()) == NULL) {
01399 wbxml_buffer_destroy(buff);
01400 wbxml_list_destroy(lresult, NULL);
01401 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01402 }
01403
01404 elt->type = WBXML_VALUE_ELEMENT_STRING;
01405 elt->u.str = buff;
01406
01407
01408 if (!wbxml_list_append(lresult, elt)) {
01409 wbxml_value_element_destroy(elt);
01410 wbxml_list_destroy(lresult, NULL);
01411 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01412 }
01413
01414
01415 if (ctx == WBXML_VALUE_ELEMENT_CTX_ATTR)
01416 {
01417
01418
01419
01420
01421 if (encoder->tree->lang->attrValueTable != NULL) {
01422
01423 j = 0;
01424 while (encoder->tree->lang->attrValueTable[j].xmlName != NULL)
01425 {
01426
01427 for (i = 0; i < wbxml_list_len(lresult); i++) {
01428 if ((elt = (WBXMLValueElement *) wbxml_list_get(lresult, i)) == NULL)
01429 continue;
01430
01431 if (elt->type != WBXML_VALUE_ELEMENT_STRING)
01432 continue;
01433
01434
01435 if (wbxml_buffer_search_cstr(elt->u.str, (WB_UTINY *)encoder->tree->lang->attrValueTable[j].xmlName, 0, &index)) {
01436
01437 if ((new_elt = wbxml_value_element_create()) == NULL) {
01438 wbxml_list_destroy(lresult, wbxml_value_element_destroy_item);
01439 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01440 }
01441
01442 new_elt->type = WBXML_VALUE_ELEMENT_ATTR_TOKEN;
01443 new_elt->u.attr = &(encoder->tree->lang->attrValueTable[j]);
01444
01445
01446 if (!wbxml_list_insert(lresult, (void *) new_elt, i + 1)) {
01447 wbxml_value_element_destroy(new_elt);
01448 wbxml_list_destroy(lresult, wbxml_value_element_destroy_item);
01449 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01450 }
01451
01452
01453 if (index + WBXML_STRLEN(encoder->tree->lang->attrValueTable[j].xmlName) < wbxml_buffer_len(elt->u.str)) {
01454
01455 if ((new_elt = wbxml_value_element_create()) == NULL) {
01456 wbxml_list_destroy(lresult, wbxml_value_element_destroy_item);
01457 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01458 }
01459
01460 new_elt->type = WBXML_VALUE_ELEMENT_STRING;
01461 new_elt->u.str = wbxml_buffer_create_from_cstr(wbxml_buffer_get_cstr(elt->u.str) + index + WBXML_STRLEN(encoder->tree->lang->attrValueTable[j].xmlName));
01462
01463
01464 if ((new_elt->u.str == NULL) ||
01465 !wbxml_list_insert(lresult, (void *) new_elt, i + 2))
01466 {
01467 wbxml_value_element_destroy(new_elt);
01468 wbxml_list_destroy(lresult, wbxml_value_element_destroy_item);
01469 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01470 }
01471 }
01472
01473
01474 wbxml_buffer_delete(elt->u.str, index, wbxml_buffer_len(elt->u.str) - index);
01475 }
01476 }
01477 j++;
01478 }
01479 }
01480 }
01481
01482
01483 if (ctx == WBXML_VALUE_ELEMENT_CTX_CONTENT)
01484 {
01485
01486
01487
01488
01491 if (encoder->tree->lang->extValueTable != NULL) {
01492
01493 j = 0;
01494 while (encoder->tree->lang->extValueTable[j].xmlName != NULL)
01495 {
01496
01497 for (i = 0; i < wbxml_list_len(lresult); i++) {
01498 if ((elt = (WBXMLValueElement *) wbxml_list_get(lresult, i)) == NULL)
01499 continue;
01500
01501 if (elt->type != WBXML_VALUE_ELEMENT_STRING)
01502 continue;
01503
01504
01505 if (WBXML_STRLEN(encoder->tree->lang->extValueTable[j].xmlName) < 2)
01506 continue;
01507
01508
01509 if (wbxml_buffer_search_cstr(elt->u.str, (WB_UTINY *) encoder->tree->lang->extValueTable[j].xmlName, 0, &index))
01510 {
01511
01512 if ((new_elt = wbxml_value_element_create()) == NULL) {
01513 wbxml_list_destroy(lresult, wbxml_value_element_destroy_item);
01514 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01515 }
01516
01517 new_elt->type = WBXML_VALUE_ELEMENT_EXTENSION;
01518 new_elt->u.ext = &(encoder->tree->lang->extValueTable[j]);
01519
01520
01521 if (!wbxml_list_insert(lresult, (void *) new_elt, i + 1)) {
01522 wbxml_value_element_destroy(new_elt);
01523 wbxml_list_destroy(lresult, wbxml_value_element_destroy_item);
01524 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01525 }
01526
01527
01528 if (index + WBXML_STRLEN(encoder->tree->lang->extValueTable[j].xmlName) < wbxml_buffer_len(elt->u.str)) {
01529
01530 if ((new_elt = wbxml_value_element_create()) == NULL) {
01531 wbxml_list_destroy(lresult, wbxml_value_element_destroy_item);
01532 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01533 }
01534
01535 new_elt->type = WBXML_VALUE_ELEMENT_STRING;
01536 new_elt->u.str = wbxml_buffer_create_from_cstr(wbxml_buffer_get_cstr(elt->u.str) + index + WBXML_STRLEN(encoder->tree->lang->extValueTable[j].xmlName));
01537
01538
01539 if ((new_elt->u.str == NULL) ||
01540 !wbxml_list_insert(lresult, (void *) new_elt, i + 2))
01541 {
01542 wbxml_value_element_destroy(new_elt);
01543 wbxml_list_destroy(lresult, wbxml_value_element_destroy_item);
01544 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01545 }
01546 }
01547
01548
01549 wbxml_buffer_delete(elt->u.str, index, wbxml_buffer_len(elt->u.str) - index);
01550 }
01551 }
01552 j++;
01553 }
01554 }
01555 }
01556
01557
01558 #if defined( WBXML_ENCODER_USE_STRTBL )
01559
01560
01561
01562
01563
01564 if (encoder->use_strtbl) {
01565
01566 for (j = 0; j < wbxml_list_len(encoder->strstbl); j++) {
01567 if ((strtbl_elt = (WBXMLStringTableElement *) wbxml_list_get(encoder->strstbl, j)) == NULL)
01568 continue;
01569
01570
01571 for (i = 0; i < wbxml_list_len(lresult); i++) {
01572 if ((elt = (WBXMLValueElement *) wbxml_list_get(lresult, i)) == NULL)
01573 continue;
01574
01575 if (elt->type != WBXML_VALUE_ELEMENT_STRING)
01576 continue;
01577
01578
01579 if (wbxml_buffer_search(elt->u.str, strtbl_elt->string, 0, &index)) {
01580
01581 if ((new_elt = wbxml_value_element_create()) == NULL) {
01582 wbxml_list_destroy(lresult, wbxml_value_element_destroy_item);
01583 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01584 }
01585
01586 new_elt->type = WBXML_VALUE_ELEMENT_TABLEREF;
01587 new_elt->u.index = strtbl_elt->offset;
01588
01589
01590 if (!wbxml_list_insert(lresult, (void *) new_elt, i + 1)) {
01591 wbxml_value_element_destroy(new_elt);
01592 wbxml_list_destroy(lresult, wbxml_value_element_destroy_item);
01593 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01594 }
01595
01596
01597 if (index + wbxml_buffer_len(strtbl_elt->string) < wbxml_buffer_len(elt->u.str)) {
01598
01599 if ((new_elt = wbxml_value_element_create()) == NULL) {
01600 wbxml_list_destroy(lresult, wbxml_value_element_destroy_item);
01601 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01602 }
01603
01604 new_elt->type = WBXML_VALUE_ELEMENT_STRING;
01605 new_elt->u.str = wbxml_buffer_create_from_cstr(wbxml_buffer_get_cstr(elt->u.str) + index + wbxml_buffer_len(strtbl_elt->string));
01606
01607
01608 if ((new_elt->u.str == NULL) ||
01609 !wbxml_list_insert(lresult, (void *) new_elt, i + 2))
01610 {
01611 wbxml_value_element_destroy(new_elt);
01612 wbxml_list_destroy(lresult, wbxml_value_element_destroy_item);
01613 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01614 }
01615 }
01616
01617
01618 wbxml_buffer_delete(elt->u.str, index, wbxml_buffer_len(elt->u.str) - index);
01619 }
01620 }
01621 }
01622 }
01623
01624 #endif
01625
01626
01627
01628
01629
01630
01631 ret = wbxml_encode_value_element_list(encoder, lresult);
01632
01633
01634 wbxml_list_destroy(lresult, wbxml_value_element_destroy_item);
01635
01636 return ret;
01637 }
01638
01639
01646 static WBXMLError wbxml_encode_value_element_list(WBXMLEncoder *encoder, WBXMLList *list)
01647 {
01648 WBXMLValueElement *elt = NULL;
01649 WB_ULONG i = 0;
01650 WBXMLError ret = WBXML_OK;
01651
01652 if (encoder == NULL)
01653 return WBXML_ERROR_INTERNAL;
01654
01655 if (list == NULL)
01656 return WBXML_OK;
01657
01658 for (i = 0; i < wbxml_list_len(list); i++) {
01659 if ((elt = (WBXMLValueElement *) wbxml_list_get(list, i)) == NULL)
01660 continue;
01661
01662 switch (elt->type) {
01663 case WBXML_VALUE_ELEMENT_STRING:
01664
01665 if (wbxml_buffer_len(elt->u.str) > 0) {
01666 if ((ret = wbxml_encode_inline_string(encoder, elt->u.str)) != WBXML_OK)
01667 return ret;
01668 }
01669 break;
01670
01671 #if defined( WBXML_ENCODER_USE_STRTBL )
01672 case WBXML_VALUE_ELEMENT_TABLEREF:
01673
01674 if ((ret = wbxml_encode_tableref(encoder, elt->u.index)) != WBXML_OK)
01675 return ret;
01676 break;
01677 #endif
01678
01679 case WBXML_VALUE_ELEMENT_EXTENSION:
01680
01681 if ((ret = wbxml_encode_inline_integer_extension_token(encoder, WBXML_EXT_T_0, elt->u.ext->wbxmlToken)) != WBXML_OK)
01682 return ret;
01683 break;
01684
01685 case WBXML_VALUE_ELEMENT_OPAQUE:
01687 break;
01688
01689 case WBXML_VALUE_ELEMENT_ATTR_TOKEN:
01690
01691 if ((ret = wbxml_encode_attr_token(encoder, elt->u.attr->wbxmlToken, elt->u.attr->wbxmlCodePage)) != WBXML_OK)
01692 return ret;
01693 break;
01694
01695 default:
01696 return WBXML_ERROR_INTERNAL;
01697 }
01698 }
01699
01700 return WBXML_OK;
01701 }
01702
01703
01712 static WBXMLError wbxml_encode_attr_start_literal(WBXMLEncoder *encoder, const WB_UTINY *attr)
01713 {
01714 #if defined( WBXML_ENCODER_USE_STRTBL )
01715 WBXMLStringTableElement *elt = NULL;
01716 WBXMLBuffer *buff = NULL;
01717 WB_ULONG index = 0;
01718 WB_BOOL added = FALSE;
01719
01720
01721 if (!encoder->use_strtbl)
01722 return WBXML_ERROR_STRTBL_DISABLED;
01723
01724
01725 if (((buff = wbxml_buffer_create(attr, WBXML_STRLEN(attr), WBXML_STRLEN(attr))) == NULL) ||
01726 ((elt = wbxml_strtbl_element_create(buff, FALSE)) == NULL) ||
01727 (!wbxml_strtbl_add_element(encoder, elt, &index, &added)))
01728 {
01729 wbxml_strtbl_element_destroy(elt);
01730 wbxml_buffer_destroy(buff);
01731 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01732 }
01733
01734
01735 if (!added)
01736 wbxml_strtbl_element_destroy(elt);
01737
01738
01739 if ((!wbxml_buffer_append_char(encoder->output, WBXML_LITERAL)) ||
01740 (!wbxml_buffer_append_mb_uint_32(encoder->output, index)))
01741 {
01742 return WBXML_ERROR_ENCODER_APPEND_DATA;
01743 }
01744
01745 return WBXML_OK;
01746 #else
01747
01748 return WBXML_ERROR_STRTBL_DISABLED;
01749 #endif
01750 }
01751
01752
01765 static WBXMLError wbxml_encode_attr_token(WBXMLEncoder *encoder, WB_UTINY token, WB_UTINY page)
01766 {
01767
01768 if (encoder->attrCodePage != page)
01769 {
01770 if ((!wbxml_buffer_append_char(encoder->output, WBXML_SWITCH_PAGE)) ||
01771 (!wbxml_buffer_append_char(encoder->output, page)))
01772 {
01773 return WBXML_ERROR_ENCODER_APPEND_DATA;
01774 }
01775
01776 encoder->attrCodePage = page;
01777 }
01778
01779
01780 if (!wbxml_buffer_append_char(encoder->output, token))
01781 return WBXML_ERROR_ENCODER_APPEND_DATA;
01782
01783 return WBXML_OK;
01784 }
01785
01786
01793 static WBXMLError wbxml_encode_inline_string(WBXMLEncoder *encoder, WBXMLBuffer *str)
01794 {
01795
01796 if (!wbxml_buffer_append_char(encoder->output, WBXML_STR_I))
01797 return WBXML_ERROR_ENCODER_APPEND_DATA;
01798
01799
01800 if (!wbxml_buffer_append(encoder->output, str))
01801 return WBXML_ERROR_ENCODER_APPEND_DATA;
01802
01803
01804 if (!wbxml_buffer_append_char(encoder->output, WBXML_STR_END))
01805 return WBXML_ERROR_ENCODER_APPEND_DATA;
01806
01807 return WBXML_OK;
01808 }
01809
01810
01819 static WBXMLError wbxml_encode_inline_integer_extension_token(WBXMLEncoder *encoder, WB_UTINY ext, WB_UTINY value)
01820 {
01821
01822 if (!wbxml_buffer_append_char(encoder->output, ext))
01823 return WBXML_ERROR_ENCODER_APPEND_DATA;
01824
01825
01826 if (!wbxml_buffer_append_mb_uint_32(encoder->output, (WB_ULONG) value))
01827 return WBXML_ERROR_ENCODER_APPEND_DATA;
01828
01829 return WBXML_OK;
01830 }
01831
01832
01841 static WBXMLError wbxml_encode_entity(WBXMLEncoder *encoder, WB_ULONG value)
01842 {
01843
01844 if (!wbxml_buffer_append_char(encoder->output, WBXML_ENTITY))
01845 return WBXML_ERROR_ENCODER_APPEND_DATA;
01846
01847
01848 if (!wbxml_buffer_append_mb_uint_32(encoder->output, value))
01849 return WBXML_ERROR_ENCODER_APPEND_DATA;
01850
01851 return WBXML_OK;
01852 }
01853
01854
01863 static WBXMLError wbxml_encode_opaque(WBXMLEncoder *encoder, WBXMLBuffer *buff)
01864 {
01865
01866 if (!wbxml_buffer_append_char(encoder->output, WBXML_OPAQUE))
01867 return WBXML_ERROR_ENCODER_APPEND_DATA;
01868
01869
01870 if (!wbxml_buffer_append_mb_uint_32(encoder->output, wbxml_buffer_len(buff)))
01871 return WBXML_ERROR_ENCODER_APPEND_DATA;
01872
01873
01874 if (!wbxml_buffer_append(encoder->output, buff))
01875 return WBXML_ERROR_ENCODER_APPEND_DATA;
01876
01877 return WBXML_OK;
01878 }
01879
01880
01881 #if defined( WBXML_ENCODER_USE_STRTBL )
01882
01889 static WBXMLError wbxml_encode_tableref(WBXMLEncoder *encoder, WB_ULONG offset)
01890 {
01891
01892 if (!wbxml_buffer_append_char(encoder->output, WBXML_STR_T))
01893 return WBXML_ERROR_ENCODER_APPEND_DATA;
01894
01895
01896 if (!wbxml_buffer_append_mb_uint_32(encoder->output, offset))
01897 return WBXML_ERROR_ENCODER_APPEND_DATA;
01898
01899 return WBXML_OK;
01900 }
01901 #endif
01902
01903
01908 static WBXMLValueElement *wbxml_value_element_create(void)
01909 {
01910 WBXMLValueElement *elt = NULL;
01911
01912 if ((elt = (WBXMLValueElement*) wbxml_malloc(sizeof(WBXMLValueElement))) == NULL)
01913 return NULL;
01914
01915 elt->type = WBXML_VALUE_ELEMENT_STRING;
01916 elt->u.str = NULL;
01917
01918 return elt;
01919 }
01920
01921
01926 static void wbxml_value_element_destroy(WBXMLValueElement *elt)
01927 {
01928 if (elt == NULL)
01929 return;
01930
01931 switch (elt->type) {
01932 case WBXML_VALUE_ELEMENT_STRING:
01933 wbxml_buffer_destroy(elt->u.str);
01934 break;
01935 case WBXML_VALUE_ELEMENT_OPAQUE:
01936 wbxml_buffer_destroy(elt->u.buff);
01937 break;
01938 default:
01939
01940 break;
01941 }
01942
01943 wbxml_free((void*) elt);
01944 }
01945
01946
01951 static void wbxml_value_element_destroy_item(void *elt)
01952 {
01953 wbxml_value_element_destroy((WBXMLValueElement *) elt);
01954 }
01955
01956
01963 static WBXMLError wbxml_encode_tree(WBXMLEncoder *encoder, WBXMLTree *tree)
01964 {
01965 WBXMLEncoder *new_encoder = NULL;
01966 WB_UTINY *wbxml = NULL;
01967 WB_ULONG wbxml_len = 0;
01968 WBXMLError ret = WBXML_OK;
01969
01970 if ((new_encoder = wbxml_encoder_duplicate(encoder)) == NULL)
01971 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01972
01973
01974 new_encoder->tree = tree;
01975
01976
01977 if ((ret = wbxml_encoder_encode_to_wbxml(new_encoder, &wbxml, &wbxml_len)) != WBXML_OK) {
01978 wbxml_encoder_destroy(new_encoder);
01979 return ret;
01980 }
01981
01982
01983 wbxml_encoder_destroy(new_encoder);
01984
01985
01986 if (!wbxml_buffer_append_char(encoder->output, WBXML_OPAQUE)) {
01987 wbxml_free(wbxml);
01988 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01989 }
01990
01991
01992 if (!wbxml_buffer_append_mb_uint_32(encoder->output, wbxml_len)) {
01993 wbxml_free(wbxml);
01994 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
01995 }
01996
01997
01998 if (!wbxml_buffer_append_data(encoder->output, wbxml, wbxml_len)) {
01999 wbxml_free(wbxml);
02000 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
02001 }
02002
02003
02004 wbxml_free(wbxml);
02005
02006 return WBXML_OK;
02007 }
02008
02009
02010
02011
02012
02013
02014 #if ( defined( WBXML_SUPPORT_SI ) || defined( WBXML_SUPPORT_EMN ) )
02015
02016
02017
02018
02019
02027 static WBXMLError wbxml_encode_datetime(WBXMLEncoder *encoder, WB_UTINY *buffer)
02028 {
02029 WBXMLBuffer *tmp = NULL;
02030 WB_ULONG i = 0;
02031 WB_UTINY ch = 0;
02032 WBXMLError ret = WBXML_OK;
02033
02034
02035 if ((tmp = wbxml_buffer_create_from_cstr(buffer)) == NULL)
02036 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
02037
02038
02039 while (i < wbxml_buffer_len(tmp)) {
02040
02041 if (!wbxml_buffer_get_char(tmp, i, &ch)) {
02042 wbxml_buffer_destroy(tmp);
02043 return WBXML_ERROR_INTERNAL;
02044 }
02045
02046 if (!WBXML_ISDIGIT(ch)) {
02047 if ((ch != 'T') && (ch != 'Z') && (ch != '-') && (ch != ':')) {
02048 wbxml_buffer_destroy(tmp);
02049 return WBXML_ERROR_BAD_DATETIME;
02050 }
02051
02052
02053 wbxml_buffer_delete(tmp, i, 1);
02054 }
02055 else
02056 i++;
02057 }
02058
02059
02060 wbxml_buffer_hex_to_binary(tmp);
02061
02062
02063 wbxml_buffer_remove_trailing_zeros(&tmp);
02064
02065
02066 ret = wbxml_encode_opaque(encoder, tmp);
02067
02068 wbxml_buffer_destroy(tmp);
02069
02070 return ret;
02071 }
02072
02073 #endif
02074
02075
02076 #if defined( WBXML_SUPPORT_WV )
02077
02078
02079
02080
02081
02092 static WBXMLError wbxml_encode_wv_content(WBXMLEncoder *encoder, WB_UTINY *buffer)
02093 {
02094 const WBXMLExtValueEntry *ext = NULL;
02095 WBXMLWVDataType data_type = WBXML_WV_DATA_TYPE_STRING;
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151 if (encoder->current_tag != NULL)
02152 {
02153 switch (encoder->current_tag->wbxmlCodePage) {
02154 case 0x00:
02155
02156 switch (encoder->current_tag->wbxmlToken) {
02157 case 0x05:
02158 case 0x18:
02159 case 0x21:
02160
02161 data_type = WBXML_WV_DATA_TYPE_BOOLEAN;
02162 break;
02163 case 0x0B:
02164 case 0x0F:
02165 case 0x1A:
02166 case 0x3C:
02167
02168 data_type = WBXML_WV_DATA_TYPE_INTEGER;
02169 break;
02170 case 0x11:
02171
02172 data_type = WBXML_WV_DATA_TYPE_DATE_AND_TIME;
02173 break;
02174 case 0x0D:
02175
02177
02178
02179
02180
02181
02182 data_type = WBXML_WV_DATA_TYPE_STRING;
02183 break;
02184 default:
02185
02186 data_type = WBXML_WV_DATA_TYPE_STRING;
02187 break;
02188 }
02189 break;
02190 case 0x01:
02191
02192 switch (encoder->current_tag->wbxmlToken) {
02193 case 0x06:
02194 case 0x0B:
02195 case 0x34:
02196 case 0x36:
02197
02198 data_type = WBXML_WV_DATA_TYPE_BOOLEAN;
02199 break;
02200 case 0x1C:
02201 case 0x25:
02202 case 0x26:
02203 case 0x27:
02204 case 0x28:
02205 case 0x32:
02206
02207 data_type = WBXML_WV_DATA_TYPE_INTEGER;
02208 break;
02209 default:
02210
02211 data_type = WBXML_WV_DATA_TYPE_STRING;
02212 break;
02213 }
02214 break;
02215 case 0x03:
02216
02217 switch (encoder->current_tag->wbxmlToken) {
02218 case 0x09:
02219
02220 data_type = WBXML_WV_DATA_TYPE_BOOLEAN;
02221 break;
02222 case 0x05:
02223 case 0x06:
02224 case 0x0C:
02225 case 0x0D:
02226 case 0x0E:
02227 case 0x12:
02228 case 0x13:
02229
02230 data_type = WBXML_WV_DATA_TYPE_INTEGER;
02231 break;
02232 default:
02233
02234 data_type = WBXML_WV_DATA_TYPE_STRING;
02235 break;
02236 }
02237 break;
02238 case 0x04:
02239
02240 switch (encoder->current_tag->wbxmlToken) {
02241 case 0x0B:
02242 case 0x1E:
02243
02244 data_type = WBXML_WV_DATA_TYPE_BOOLEAN;
02245 break;
02246 default:
02247
02248 data_type = WBXML_WV_DATA_TYPE_STRING;
02249 break;
02250 }
02251 break;
02252 case 0x06:
02253
02254 switch (encoder->current_tag->wbxmlToken) {
02255 case 0x08:
02256
02257 data_type = WBXML_WV_DATA_TYPE_BOOLEAN;
02258 break;
02259 case 0x1A:
02260
02261 data_type = WBXML_WV_DATA_TYPE_DATE_AND_TIME;
02262 break;
02263 default:
02264
02265 data_type = WBXML_WV_DATA_TYPE_STRING;
02266 break;
02267 }
02268 break;
02269 case 0x07:
02270
02271 switch (encoder->current_tag->wbxmlToken) {
02272 case 0x21:
02273 case 0x10:
02274 case 0x22:
02275
02276 data_type = WBXML_WV_DATA_TYPE_BOOLEAN;
02277 break;
02278 default:
02279
02280 data_type = WBXML_WV_DATA_TYPE_STRING;
02281 break;
02282 }
02283 break;
02284 case 0x09:
02285
02286 switch (encoder->current_tag->wbxmlToken) {
02287 case 0x05:
02288
02289 data_type = WBXML_WV_DATA_TYPE_BOOLEAN;
02290 break;
02291 case 0x08:
02292 case 0x0A:
02293
02294 data_type = WBXML_WV_DATA_TYPE_INTEGER;
02295 break;
02296 default:
02297
02298 data_type = WBXML_WV_DATA_TYPE_STRING;
02299 break;
02300 }
02301 break;
02302 default:
02303 data_type = WBXML_WV_DATA_TYPE_STRING;
02304 break;
02305 }
02306 }
02307
02308
02309
02310
02311
02312
02313 switch (data_type) {
02314 case WBXML_WV_DATA_TYPE_INTEGER:
02315
02316 return wbxml_encode_wv_integer(encoder, buffer);
02317 break;
02318 case WBXML_WV_DATA_TYPE_DATE_AND_TIME:
02319
02320
02321
02322
02323 break;
02324 case WBXML_WV_DATA_TYPE_BINARY:
02326 break;
02327 case WBXML_WV_DATA_TYPE_BOOLEAN:
02328
02329 case WBXML_WV_DATA_TYPE_STRING:
02330
02331 if ((ext = wbxml_tables_get_ext_from_xml(encoder->tree->lang, buffer)) != NULL)
02332 return wbxml_encode_inline_integer_extension_token(encoder, WBXML_EXT_T_0, ext->wbxmlToken);
02333 else {
02334 if (WBXML_STRLEN(buffer) == 1)
02335 {
02341
02342
02343
02344
02345 }
02346
02347
02348 }
02349 break;
02350 default:
02351
02352 break;
02353 }
02354
02355 return WBXML_NOT_ENCODED;
02356 }
02357
02358
02365 static WBXMLError wbxml_encode_wv_integer(WBXMLEncoder *encoder, WB_UTINY *buffer)
02366 {
02367 WB_UTINY octets[4];
02368 WB_ULONG the_int = 0, i = 0, start = 0;
02369
02370 if ((encoder == NULL) || (buffer == NULL))
02371 return WBXML_ERROR_INTERNAL;
02372
02373 the_int = (WB_ULONG) atol((const WB_TINY *) buffer);
02374
02375 for (i = 3; the_int > 0 && i >= 0; i--) {
02376 octets[i] = (WB_UTINY)(the_int & 0xff);
02377 the_int >>= 8;
02378 }
02379
02380 start = i + 1;
02381
02382
02383 if (!wbxml_buffer_append_char(encoder->output, WBXML_OPAQUE))
02384 return WBXML_ERROR_ENCODER_APPEND_DATA;
02385
02386
02387 if (!wbxml_buffer_append_mb_uint_32(encoder->output, 4 - start))
02388 return WBXML_ERROR_ENCODER_APPEND_DATA;
02389
02390
02391 if (!wbxml_buffer_append_data(encoder->output, octets + start, (WB_UTINY)(4 - start)))
02392 return WBXML_ERROR_ENCODER_APPEND_DATA;
02393
02394 return WBXML_OK;
02395 }
02396
02397
02422 static WBXMLError wbxml_encode_wv_datetime(WBXMLEncoder *encoder, WB_UTINY *buffer)
02423 {
02426 return WBXML_ERROR_NOT_IMPLEMENTED;
02427
02428 #if 0
02429 WBXMLBuffer *tmp = NULL;
02430 WB_ULONG i = 0, len = 0;
02431 WB_UTINY ch = 0;
02432 WBXMLError ret = WBXML_OK;
02433 WB_BOOL is_utc = FALSE;
02434
02435 len = WBXML_STRLEN(buffer);
02436
02437
02438 if ((len != 15) && (len != 16))
02439 return WBXML_ERROR_WV_DATETIME_FORMAT;
02440
02441
02442 if ((*buffer)[8] != 'T')
02443 return WBXML_ERROR_WV_DATETIME_FORMAT;
02444
02445
02446 if (len == 16) {
02447 if ((*buffer)[15] != 'Z')
02448 return WBXML_ERROR_WV_DATETIME_FORMAT;
02449
02450
02451 is_utc = TRUE;
02452 }
02453
02454
02455 if ((tmp = wbxml_buffer_create_from_cstr(buffer)) == NULL)
02456 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
02457
02458
02459 if (is_utc)
02460 wbxml_buffer_delete(tmp, 15, 1);
02461
02462 wbxml_buffer_delete(tmp, 8, 1);
02463
02464
02465 while (i < wbxml_buffer_len(tmp)) {
02466
02467 if (!wbxml_buffer_get_char(tmp, i, &ch)) {
02468 wbxml_buffer_destroy(tmp);
02469 return WBXML_ERROR_INTERNAL;
02470 }
02471
02472 if (!WBXML_ISDIGIT(ch)) {
02473 wbxml_buffer_destroy(tmp);
02474 return WBXML_ERROR_WV_DATETIME_FORMAT;
02475 }
02476 else
02477 i++;
02478 }
02479
02480
02481 wbxml_buffer_hex_to_binary(tmp);
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498 ret = wbxml_encode_opaque(encoder, tmp);
02499
02500 wbxml_buffer_destroy(tmp);
02501
02502 return ret;
02503 #endif
02504 }
02505
02506 #endif
02507
02508
02509 #if defined( WBXML_SUPPORT_DRMREL )
02510
02511
02512
02513
02514
02524 static WBXMLError wbxml_encode_drmrel_content(WBXMLEncoder *encoder, WB_UTINY *buffer)
02525 {
02526 WB_UTINY *data = NULL;
02527 WB_LONG data_len = 0;
02528
02529 if (encoder->current_tag != NULL)
02530 {
02531 if ((encoder->current_tag->wbxmlCodePage == 0x00) &&
02532 (encoder->current_tag->wbxmlToken == 0x0C))
02533 {
02534
02535
02536
02537 if ((data_len = wbxml_base64_decode(buffer, &data)) < 0)
02538 return WBXML_NOT_ENCODED;
02539
02540
02541 if (!wbxml_buffer_append_char(encoder->output, WBXML_OPAQUE))
02542 return WBXML_ERROR_ENCODER_APPEND_DATA;
02543
02544
02545 if (!wbxml_buffer_append_mb_uint_32(encoder->output, (WB_ULONG) data_len))
02546 return WBXML_ERROR_ENCODER_APPEND_DATA;
02547
02548
02549 if (!wbxml_buffer_append_data(encoder->output, data, data_len))
02550 return WBXML_ERROR_ENCODER_APPEND_DATA;
02551
02552
02553 wbxml_free(data);
02554
02555 return WBXML_OK;
02556 }
02557 }
02558
02559 return WBXML_NOT_ENCODED;
02560 }
02561
02562 #endif
02563
02564
02565 #if defined( WBXML_ENCODER_USE_STRTBL )
02566
02567
02568
02569
02570
02577 static WBXMLStringTableElement *wbxml_strtbl_element_create(WBXMLBuffer *string, WB_BOOL is_stat)
02578 {
02579 WBXMLStringTableElement *elt = NULL;
02580
02581 if ((elt = (WBXMLStringTableElement *) wbxml_malloc(sizeof(WBXMLStringTableElement))) == NULL)
02582 return NULL;
02583
02584 elt->string = string;
02585 elt->offset = 0;
02586 elt->count = 0;
02587 elt->stat = is_stat;
02588
02589 return elt;
02590 }
02591
02592
02597 static void wbxml_strtbl_element_destroy(WBXMLStringTableElement *element)
02598 {
02599 if (element == NULL)
02600 return;
02601
02602 if (!element->stat)
02603 wbxml_buffer_destroy(element->string);
02604
02605 wbxml_free(element);
02606 }
02607
02608
02613 static void wbxml_strtbl_element_destroy_item(void *element)
02614 {
02615 wbxml_strtbl_element_destroy((WBXMLStringTableElement *) element);
02616 }
02617
02618
02624 static WBXMLError wbxml_strtbl_initialize(WBXMLEncoder *encoder, WBXMLTreeNode *root)
02625 {
02626 WBXMLList *strings = NULL, *one_ref = NULL;
02627 WBXMLError ret;
02628
02629 if ((strings = wbxml_list_create()) == NULL)
02630 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
02631
02632
02633
02634
02635 wbxml_strtbl_collect_strings(encoder, root, strings);
02636
02637
02638
02639
02640
02641
02642 if ((ret = wbxml_strtbl_check_references(encoder, &strings, &one_ref, TRUE)) != WBXML_OK) {
02643 wbxml_list_destroy(strings, NULL);
02644 return ret;
02645 }
02646
02647
02648
02649
02650
02651
02652 if ((ret = wbxml_strtbl_collect_words(one_ref, &strings)) != WBXML_OK) {
02653 wbxml_list_destroy(one_ref, wbxml_strtbl_element_destroy_item);
02654 return ret;
02655 }
02656
02657
02658 wbxml_list_destroy(one_ref, wbxml_strtbl_element_destroy_item);
02659 one_ref = NULL;
02660
02661
02662 if (strings != NULL)
02663 wbxml_strtbl_check_references(encoder, &strings, &one_ref, FALSE);
02664
02665
02666
02667
02668 wbxml_list_destroy(one_ref, wbxml_strtbl_element_destroy_item);
02669
02670 return WBXML_OK;
02671 }
02672
02673
02680 static void wbxml_strtbl_collect_strings(WBXMLEncoder *encoder, WBXMLTreeNode *node, WBXMLList *strings)
02681 {
02682 WBXMLTreeAttribute *attribute = NULL;
02683 const WBXMLAttrEntry *attr_entry = NULL;
02684 WB_UTINY *value_left = NULL;
02685
02686 switch (node->type)
02687 {
02688 case WBXML_TREE_TEXT_NODE:
02689
02690 if (wbxml_buffer_contains_only_whitespaces(node->content))
02691 break;
02692
02695
02696 if (wbxml_buffer_len(node->content) > WBXML_ENCODER_STRING_TABLE_MIN) {
02697 wbxml_list_append(strings, node->content);
02698 WBXML_DEBUG((WBXML_ENCODER, "Strtbl - Collecting String: %s", wbxml_buffer_get_cstr(node->content)));
02699 }
02700 break;
02701
02702 case WBXML_TREE_ELEMENT_NODE:
02703
02704 attribute = node->attrs;
02705 while (attribute != NULL) {
02706
02707 if (wbxml_buffer_len(attribute->attr->value) > WBXML_ENCODER_STRING_TABLE_MIN) {
02708
02709 attr_entry = wbxml_tables_get_attr_from_xml(encoder->tree->lang,
02710 (WB_UTINY *) wbxml_attribute_get_xml_name(attribute->attr),
02711 (WB_UTINY *) wbxml_attribute_get_xml_value(attribute->attr),
02712 &value_left);
02713
02714
02715
02716
02717
02718
02719 if ((attr_entry == NULL) || ((attr_entry != NULL) && (value_left == (WB_UTINY *) wbxml_attribute_get_xml_value(attribute->attr))))
02720 {
02721
02722 if (!wbxml_tables_contains_attr_value_from_xml(encoder->tree->lang,
02723 (WB_UTINY *) wbxml_attribute_get_xml_value(attribute->attr)))
02724 {
02725 wbxml_list_append(strings, attribute->attr->value);
02726 WBXML_DEBUG((WBXML_ENCODER, "Strtbl - Collecting String: %s", wbxml_buffer_get_cstr(attribute->attr->value)));
02727 }
02728 }
02729 }
02730 attribute = attribute->next;
02731 }
02732 break;
02733
02734 default:
02735
02736 break;
02737 }
02738
02739 if (node->children != NULL)
02740 wbxml_strtbl_collect_strings(encoder, node->children, strings);
02741
02742 if (node->next != NULL)
02743 wbxml_strtbl_collect_strings(encoder, node->next, strings);
02744 }
02745
02746
02753 static WBXMLError wbxml_strtbl_collect_words(WBXMLList *elements, WBXMLList **result)
02754 {
02755 WBXMLStringTableElement *elt = NULL;
02756 WBXMLList *list = NULL, *temp_list = NULL;
02757 WBXMLBuffer *word = NULL;
02758 WB_ULONG i = 0;
02759
02760 *result = NULL;
02761
02762 for (i = 0; i < wbxml_list_len(elements); i++)
02763 {
02764 elt = (WBXMLStringTableElement *) wbxml_list_get(elements, i);
02765
02766 if (list == NULL) {
02767 if ((list = wbxml_buffer_split_words(elt->string)) == NULL) {
02768 wbxml_list_destroy(list, wbxml_buffer_destroy_item);
02769 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
02770 }
02771 } else {
02772 if ((temp_list = wbxml_buffer_split_words(elt->string)) == NULL) {
02773 wbxml_list_destroy(list, wbxml_buffer_destroy_item);
02774 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
02775 }
02776
02777 while ((word = wbxml_list_extract_first(temp_list)) != NULL) {
02778 if (!wbxml_list_append(list, word)) {
02779 wbxml_buffer_destroy(word);
02780 wbxml_list_destroy(temp_list, wbxml_buffer_destroy_item);
02781 wbxml_list_destroy(list, wbxml_buffer_destroy_item);
02782 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
02783 }
02784 }
02785
02786 wbxml_list_destroy(temp_list, NULL);
02787 }
02788 }
02789
02790 *result = list;
02791
02792 return WBXML_OK;
02793 }
02794
02795
02801 static void wbxml_strtbl_construct(WB_UTINY *buff, WBXMLList *strstbl)
02802 {
02803 WBXMLStringTableElement *elt = NULL;
02804 WB_ULONG i = 0, buff_index = 0;
02805
02806 if ((buff == NULL) || (strstbl == NULL))
02807 return;
02808
02809 for (i = 0; i < wbxml_list_len(strstbl); i++)
02810 {
02811 if ((elt = wbxml_list_get(strstbl, i)) == NULL)
02812 continue;
02813
02814 memcpy(buff + buff_index, wbxml_buffer_get_cstr(elt->string), wbxml_buffer_len(elt->string));
02815
02816 buff[buff_index + wbxml_buffer_len(elt->string)] = WBXML_STR_END;
02817 buff_index += wbxml_buffer_len(elt->string) + 1;
02818 }
02819 }
02820
02821
02832 static WBXMLError wbxml_strtbl_check_references(WBXMLEncoder *encoder, WBXMLList **strings, WBXMLList **one_ref, WB_BOOL stat_buff)
02833 {
02834 WBXMLList *referenced = NULL, *result = NULL;
02835 WBXMLBuffer *string = NULL;
02836 WBXMLStringTableElement *ref = NULL;
02837 WB_ULONG j = 0;
02838 WB_BOOL added = FALSE;
02839
02840 if ((strings == NULL) || (one_ref == NULL))
02841 return WBXML_ERROR_INTERNAL;
02842
02843 *one_ref = NULL;
02844
02845
02846 if ((referenced = wbxml_list_create()) == NULL)
02847 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
02848
02849
02850
02851
02852
02853
02854 while (wbxml_list_len(*strings) > 0)
02855 {
02856 string = (WBXMLBuffer *) wbxml_list_extract_first(*strings);
02857
02858
02859 for (j = 0; j < wbxml_list_len(referenced); j++)
02860 {
02861 ref = (WBXMLStringTableElement *) wbxml_list_get(referenced, j);
02862
02863 if (wbxml_buffer_compare(ref->string, string) == 0)
02864 {
02865 if (!stat_buff)
02866 wbxml_buffer_destroy(string);
02867
02868 string = NULL;
02869 ref->count++;
02870 break;
02871 }
02872 }
02873
02874 if (string != NULL)
02875 {
02876
02877 if ((ref = wbxml_strtbl_element_create(string, stat_buff)) == NULL)
02878 {
02879 wbxml_list_destroy(referenced, wbxml_strtbl_element_destroy_item);
02880
02881 if (!stat_buff)
02882 wbxml_list_destroy(*strings, wbxml_buffer_destroy_item);
02883 else
02884 wbxml_list_destroy(*strings, NULL);
02885
02886 *strings = NULL;
02887 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
02888 }
02889
02890 ref->count++;
02891
02892 if (!wbxml_list_append(referenced, (void *) ref))
02893 {
02894 wbxml_list_destroy(referenced, wbxml_strtbl_element_destroy_item);
02895
02896 if (!stat_buff)
02897 wbxml_list_destroy(*strings, wbxml_buffer_destroy_item);
02898 else
02899 wbxml_list_destroy(*strings, NULL);
02900
02901 *strings = NULL;
02902 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
02903 }
02904 }
02905 }
02906
02907
02908 wbxml_list_destroy(*strings, NULL);
02909 *strings = NULL;
02910
02911
02912
02913
02914
02915
02916 if ((result = wbxml_list_create()) == NULL) {
02917 wbxml_list_destroy(referenced, wbxml_strtbl_element_destroy_item);
02918 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
02919 }
02920
02921 while (wbxml_list_len(referenced) > 0)
02922 {
02923 ref = (WBXMLStringTableElement *) wbxml_list_extract_first(referenced);
02924 if ((ref->count > 1) && (wbxml_buffer_len(ref->string) > WBXML_ENCODER_STRING_TABLE_MIN)) {
02925
02926 if (!wbxml_strtbl_add_element(encoder, ref, NULL, &added)) {
02927 wbxml_strtbl_element_destroy(ref);
02928 wbxml_list_destroy(referenced, wbxml_strtbl_element_destroy_item);
02929 wbxml_list_destroy(result, wbxml_strtbl_element_destroy_item);
02930 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
02931 }
02932
02933 if (!added) {
02934 wbxml_strtbl_element_destroy(ref);
02935 }
02936 }
02937 else {
02938
02939 if (!wbxml_list_append(result, (void *) ref)) {
02940 wbxml_strtbl_element_destroy(ref);
02941 wbxml_list_destroy(referenced, wbxml_strtbl_element_destroy_item);
02942 wbxml_list_destroy(result, wbxml_strtbl_element_destroy_item);
02943 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
02944 }
02945 }
02946 }
02947
02948 wbxml_list_destroy(referenced, wbxml_strtbl_element_destroy_item);
02949
02950 *one_ref = result;
02951
02952 return WBXML_OK;
02953 }
02954
02955
02964 static WB_BOOL wbxml_strtbl_add_element(WBXMLEncoder *encoder, WBXMLStringTableElement *elt, WB_ULONG *index, WB_BOOL *added)
02965 {
02966 WBXMLStringTableElement *elt_tmp = NULL;
02967 WB_ULONG i = 0;
02968
02969 if ((encoder == NULL) || (encoder->strstbl == NULL) || (elt == NULL) || (elt->string == NULL))
02970 return FALSE;
02971
02972 *added = FALSE;
02973
02974
02975 for (i = 0; i < wbxml_list_len(encoder->strstbl); i++)
02976 {
02977 if ((elt_tmp = wbxml_list_get(encoder->strstbl, i)) == NULL)
02978 continue;
02979
02980 if ((wbxml_buffer_len(elt_tmp->string) == wbxml_buffer_len(elt->string)) &&
02981 (wbxml_buffer_compare(elt_tmp->string, elt->string) == 0))
02982 {
02983
02984 if (index != NULL)
02985 *index = elt_tmp->offset;
02986 return TRUE;
02987 }
02988 }
02989
02990
02991 elt->offset = encoder->strstbl_len;
02992
02993 if (!wbxml_list_append(encoder->strstbl, (void *) elt))
02994 return FALSE;
02995
02996
02997 if (index != NULL)
02998 *index = encoder->strstbl_len;
02999
03000
03001 encoder->strstbl_len += wbxml_buffer_len(elt->string) + 1;
03002
03003 *added = TRUE;
03004
03005 return TRUE;
03006 }
03007
03008 #endif
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03026 static WBXMLError xml_build_result(WBXMLEncoder *encoder, WB_UTINY **xml)
03027 {
03028 WBXMLBuffer *header = NULL;
03029 WB_ULONG xml_len = 0;
03030
03031
03032 if ((header = wbxml_buffer_create("", 0, WBXML_ENCODER_XML_HEADER_MALLOC_BLOCK)) == NULL)
03033 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
03034
03035
03036 if (encoder->xml_encode_header) {
03037 if (!xml_fill_header(encoder, header)) {
03038 wbxml_buffer_destroy(header);
03039 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
03040 }
03041 }
03042
03043
03044 xml_len = wbxml_buffer_len(header) + wbxml_buffer_len(encoder->output);
03045
03046
03047 *xml = (WB_UTINY *) wbxml_malloc((xml_len + 1) * sizeof(WB_UTINY));
03048 if (*xml == NULL) {
03049 wbxml_buffer_destroy(header);
03050 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
03051 }
03052
03053
03054 memcpy(*xml, wbxml_buffer_get_cstr(header), wbxml_buffer_len(header));
03055
03056
03057 memcpy(*xml + wbxml_buffer_len(header), wbxml_buffer_get_cstr(encoder->output), wbxml_buffer_len(encoder->output));
03058
03059
03060 (*xml)[xml_len] = '\0';
03061
03062
03063 wbxml_buffer_destroy(header);
03064
03065 return WBXML_OK;
03066 }
03067
03068
03075 static WB_BOOL xml_fill_header(WBXMLEncoder *encoder, WBXMLBuffer *header)
03076 {
03077 if ((encoder == NULL) || (header == NULL))
03078 return FALSE;
03079
03080
03081 if (!wbxml_buffer_append_cstr(header, WBXML_ENCODER_XML_HEADER))
03082 return FALSE;
03083
03084
03085 if (encoder->xml_gen_type == WBXML_ENCODER_XML_GEN_INDENT) {
03086 if (!xml_encode_new_line(header))
03087 return WBXML_ERROR_ENCODER_APPEND_DATA;
03088 }
03089
03090
03091 if (!wbxml_buffer_append_cstr(header, WBXML_ENCODER_XML_DOCTYPE))
03092 return FALSE;
03093
03094
03095 if (!wbxml_buffer_append_cstr(header, encoder->tree->lang->publicID->xmlRootElt))
03096 return FALSE;
03097
03098
03099 if (!wbxml_buffer_append_cstr(header, WBXML_ENCODER_XML_PUBLIC))
03100 return FALSE;
03101
03102
03103 if (!wbxml_buffer_append_cstr(header, encoder->tree->lang->publicID->xmlPublicID))
03104 return FALSE;
03105
03106
03107 if (!wbxml_buffer_append_cstr(header, WBXML_ENCODER_XML_DTD))
03108 return FALSE;
03109
03110
03111 if (!wbxml_buffer_append_cstr(header, encoder->tree->lang->publicID->xmlDTD))
03112 return FALSE;
03113
03114
03115 if (!wbxml_buffer_append_cstr(header, WBXML_ENCODER_XML_END_DTD))
03116 return FALSE;
03117
03118
03119 if (encoder->xml_gen_type == WBXML_ENCODER_XML_GEN_INDENT) {
03120 if (!xml_encode_new_line(header))
03121 return WBXML_ERROR_ENCODER_APPEND_DATA;
03122 }
03123
03124 return TRUE;
03125 }
03126
03127
03128
03129
03130
03131
03138 static WBXMLError xml_encode_tag(WBXMLEncoder *encoder, WBXMLTreeNode *node)
03139 {
03140 const WB_TINY *ns = NULL;
03141 WB_UTINY i;
03142
03143
03144 if (node->name->type == WBXML_VALUE_TOKEN)
03145 encoder->current_tag = node->name->u.token;
03146 else
03147 encoder->current_tag = NULL;
03148
03149
03150 if (encoder->xml_gen_type == WBXML_ENCODER_XML_GEN_INDENT) {
03151 for (i=0; i<(encoder->indent * encoder->indent_delta); i++) {
03152 if (!wbxml_buffer_append_char(encoder->output, ' '))
03153 return WBXML_ERROR_ENCODER_APPEND_DATA;
03154 }
03155 }
03156
03157
03158 if (!wbxml_buffer_append_char(encoder->output, '<'))
03159 return WBXML_ERROR_ENCODER_APPEND_DATA;
03160
03161
03162 if (!wbxml_buffer_append_cstr(encoder->output, wbxml_tag_get_xml_name(node->name)))
03163 return WBXML_ERROR_ENCODER_APPEND_DATA;
03164
03165
03166 if ((encoder->tree->lang->nsTable != NULL) &&
03167 ((node->parent == NULL) ||
03168 ((node->parent->type == WBXML_TREE_ELEMENT_NODE) &&
03169 (node->parent->name->type == WBXML_VALUE_TOKEN) &&
03170 (node->type == WBXML_TREE_ELEMENT_NODE) &&
03171 (node->name->type == WBXML_VALUE_TOKEN) &&
03172 (node->parent->name->u.token->wbxmlCodePage != node->name->u.token->wbxmlCodePage))))
03173 {
03174 if ((ns = wbxml_tables_get_xmlns(encoder->tree->lang->nsTable, node->name->u.token->wbxmlCodePage)) != NULL)
03175 {
03176
03177 if (!wbxml_buffer_append_cstr(encoder->output, " xmlns=\""))
03178 return WBXML_ERROR_ENCODER_APPEND_DATA;
03179
03180
03181 if (!wbxml_buffer_append_cstr(encoder->output, ns))
03182 return WBXML_ERROR_ENCODER_APPEND_DATA;
03183
03184
03185 if (!wbxml_buffer_append_char(encoder->output, '"'))
03186 return WBXML_ERROR_ENCODER_APPEND_DATA;
03187 }
03188 }
03189
03190 return WBXML_OK;
03191 }
03192
03193
03200 static WBXMLError xml_encode_end_tag(WBXMLEncoder *encoder, WBXMLTreeNode *node)
03201 {
03202 WB_UTINY i;
03203
03204 if (encoder->xml_gen_type == WBXML_ENCODER_XML_GEN_INDENT) {
03205
03206 if (encoder->in_content) {
03207 if (!xml_encode_new_line(encoder->output))
03208 return WBXML_ERROR_ENCODER_APPEND_DATA;
03209 }
03210
03211 encoder->indent--;
03212
03213
03214 for (i=0; i<(encoder->indent * encoder->indent_delta); i++) {
03215 if (!wbxml_buffer_append_char(encoder->output, ' '))
03216 return WBXML_ERROR_ENCODER_APPEND_DATA;
03217 }
03218 }
03219
03220
03221 if (!wbxml_buffer_append_cstr(encoder->output, "</"))
03222 return WBXML_ERROR_ENCODER_APPEND_DATA;
03223
03224
03225 if (!wbxml_buffer_append_cstr(encoder->output, wbxml_tag_get_xml_name(node->name)))
03226 return WBXML_ERROR_ENCODER_APPEND_DATA;
03227
03228
03229 if (!wbxml_buffer_append_char(encoder->output, '>'))
03230 return WBXML_ERROR_ENCODER_APPEND_DATA;
03231
03232
03233 if (encoder->xml_gen_type == WBXML_ENCODER_XML_GEN_INDENT) {
03234 if (!xml_encode_new_line(encoder->output))
03235 return WBXML_ERROR_ENCODER_APPEND_DATA;
03236 }
03237
03238
03239 encoder->current_tag = NULL;
03240
03241 encoder->in_content = FALSE;
03242
03243 return WBXML_OK;
03244 }
03245
03246
03253 static WBXMLError xml_encode_attr(WBXMLEncoder *encoder, WBXMLAttribute *attribute)
03254 {
03255
03256 if (!wbxml_buffer_append_char(encoder->output, ' '))
03257 return WBXML_ERROR_ENCODER_APPEND_DATA;
03258
03259
03260 if (!wbxml_buffer_append_cstr(encoder->output, wbxml_attribute_get_xml_name(attribute)))
03261 return WBXML_ERROR_ENCODER_APPEND_DATA;
03262
03263
03264 if (!wbxml_buffer_append_cstr(encoder->output, "=\""))
03265 return WBXML_ERROR_ENCODER_APPEND_DATA;
03266
03267 if (wbxml_attribute_get_xml_value(attribute) != NULL) {
03268
03269 if (encoder->xml_gen_type == WBXML_ENCODER_XML_GEN_CANONICAL) {
03270 WBXMLBuffer *tmp = NULL;
03271
03272
03273 if ((tmp = wbxml_buffer_create_from_cstr(wbxml_attribute_get_xml_value(attribute))) == NULL)
03274 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
03275
03276
03277 xml_normalize(tmp);
03278
03279
03280 if (!wbxml_buffer_append(encoder->output, tmp)) {
03281 wbxml_buffer_destroy(tmp);
03282 return WBXML_ERROR_ENCODER_APPEND_DATA;
03283 }
03284
03285 wbxml_buffer_destroy(tmp);
03286 }
03287 else {
03288
03289 if (!wbxml_buffer_append_cstr(encoder->output, wbxml_attribute_get_xml_value(attribute)))
03290 return WBXML_ERROR_ENCODER_APPEND_DATA;
03291 }
03292 }
03293
03294
03295 if (!wbxml_buffer_append_char(encoder->output, '"'))
03296 return WBXML_ERROR_ENCODER_APPEND_DATA;
03297
03298 return WBXML_OK;
03299 }
03300
03301
03307 static WBXMLError xml_encode_end_attrs(WBXMLEncoder *encoder)
03308 {
03309
03310 if (!wbxml_buffer_append_char(encoder->output, '>'))
03311 return WBXML_ERROR_ENCODER_APPEND_DATA;
03312
03313
03314 if (encoder->xml_gen_type == WBXML_ENCODER_XML_GEN_INDENT) {
03315 if (!xml_encode_new_line(encoder->output))
03316 return WBXML_ERROR_ENCODER_APPEND_DATA;
03317
03318 encoder->indent++;
03319 }
03320
03321 return WBXML_OK;
03322 }
03323
03324
03331 static WBXMLError xml_encode_text(WBXMLEncoder *encoder, WBXMLBuffer *str)
03332 {
03333 WBXMLBuffer *tmp = NULL;
03334 WB_UTINY i;
03335
03336
03337 if ((tmp = wbxml_buffer_duplicate(str)) == NULL)
03338 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
03339
03340
03341 if ((encoder->xml_gen_type == WBXML_ENCODER_XML_GEN_INDENT) &&
03342 (!encoder->in_content))
03343 {
03344
03345 for (i=0; i<(encoder->indent * encoder->indent_delta); i++) {
03346 if (!wbxml_buffer_append_char(encoder->output, ' ')) {
03347 wbxml_buffer_destroy(tmp);
03348 return WBXML_ERROR_ENCODER_APPEND_DATA;
03349 }
03350 }
03351 }
03352
03353 #if defined( WBXML_SUPPORT_SYNCML )
03354
03355 if (((encoder->tree->lang->langID == WBXML_LANG_SYNCML_SYNCML10) ||
03356 (encoder->tree->lang->langID == WBXML_LANG_SYNCML_SYNCML11)) &&
03357 (encoder->current_tag != NULL) &&
03358 (encoder->current_tag->wbxmlCodePage == 0x01 ) &&
03359 (encoder->current_tag->wbxmlToken == 0x13 ) &&
03360 (wbxml_buffer_compare_cstr(tmp, "application/vnd.syncml-devinf+wbxml") == 0))
03361 {
03362 wbxml_buffer_destroy(tmp);
03363
03364
03365 if ((tmp = wbxml_buffer_create_from_cstr("application/vnd.syncml-devinf+xml")) == NULL)
03366 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
03367 }
03368 #endif
03369
03370
03371 if (encoder->xml_gen_type == WBXML_ENCODER_XML_GEN_CANONICAL)
03372 xml_normalize(tmp);
03373
03374
03375 if (!wbxml_buffer_append(encoder->output, tmp)) {
03376 wbxml_buffer_destroy(tmp);
03377 return WBXML_ERROR_ENCODER_APPEND_DATA;
03378 }
03379
03380 encoder->in_content = TRUE;
03381
03382
03383 wbxml_buffer_destroy(tmp);
03384
03385 return WBXML_OK;
03386 }
03387
03388
03394 static WB_BOOL xml_encode_new_line(WBXMLBuffer *buff)
03395 {
03396 if (buff == NULL)
03397 return FALSE;
03398
03399 return wbxml_buffer_append_data(buff, WBXML_ENCODER_XML_NEW_LINE, WBXML_STRLEN(WBXML_ENCODER_XML_NEW_LINE));
03400
03401 }
03402
03403
03409 static WB_BOOL xml_normalize(WBXMLBuffer *buff)
03410 {
03411 WB_ULONG i = 0;
03412 WB_UTINY ch;
03413
03414 for (i = 0; i < wbxml_buffer_len(buff); i++) {
03415 if (!wbxml_buffer_get_char(buff, i, &ch))
03416 continue;
03417
03418 switch (ch) {
03419 case '<':
03420
03421 wbxml_buffer_delete(buff, i, 1);
03422
03423
03424 if (!wbxml_buffer_insert_cstr(buff, (WB_UTINY *) xml_lt, i))
03425 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
03426
03427 break;
03428
03429 case '>':
03430
03431 wbxml_buffer_delete(buff, i, 1);
03432
03433
03434 if (!wbxml_buffer_insert_cstr(buff, (WB_UTINY *) xml_gt, i))
03435 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
03436
03437 break;
03438
03439 case '&':
03440
03441 wbxml_buffer_delete(buff, i, 1);
03442
03443
03444 if (!wbxml_buffer_insert_cstr(buff, (WB_UTINY *) xml_amp, i))
03445 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
03446
03447 break;
03448
03449 case '"':
03450
03451 wbxml_buffer_delete(buff, i, 1);
03452
03453
03454 if (!wbxml_buffer_insert_cstr(buff, (WB_UTINY *) xml_quot, i))
03455 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
03456
03457 break;
03458
03459 case '\r':
03460
03461 wbxml_buffer_delete(buff, i, 1);
03462
03463
03464 if (!wbxml_buffer_insert_cstr(buff, (WB_UTINY *) xml_slashr, i))
03465 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
03466
03467 break;
03468
03469 case '\n':
03470
03471 wbxml_buffer_delete(buff, i, 1);
03472
03473
03474 if (!wbxml_buffer_insert_cstr(buff, (WB_UTINY *) xml_slashn, i))
03475 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
03476
03477 break;
03478
03479 case '\t':
03480
03481 wbxml_buffer_delete(buff, i, 1);
03482
03483
03484 if (!wbxml_buffer_insert_cstr(buff, (WB_UTINY *) xml_tab, i))
03485 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
03486
03487 break;
03488
03489 default:
03490
03491 break;
03492 }
03493 }
03494
03495 return WBXML_OK;
03496 }
03497
03498
03505 static WBXMLError xml_encode_tree(WBXMLEncoder *encoder, WBXMLTree *tree)
03506 {
03507 WBXMLEncoder *new_encoder = NULL;
03508 WB_UTINY *xml = NULL;
03509 WBXMLError ret = WBXML_OK;
03510
03511 if ((new_encoder = wbxml_encoder_duplicate(encoder)) == NULL)
03512 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
03513
03514
03515 new_encoder->tree = tree;
03516
03517
03518 if ((ret = wbxml_encoder_encode_to_xml(new_encoder, &xml)) != WBXML_OK) {
03519 wbxml_encoder_destroy(new_encoder);
03520 return ret;
03521 }
03522
03523
03524 wbxml_encoder_destroy(new_encoder);
03525
03526
03527 if (!wbxml_buffer_append_cstr(encoder->output, xml)) {
03528 wbxml_free(xml);
03529 return WBXML_ERROR_NOT_ENOUGH_MEMORY;
03530 }
03531
03532
03533 wbxml_free(xml);
03534
03535 return WBXML_OK;
03536 }