xml_shared.c
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:6k
源码类别:

手机WAP编程

开发平台:

WINDOWS

  1. /*
  2.  * xml_shared.c: Common functions of xml compilers (mainly charset handling 
  3.  * and operations with wbxml binary not using a string table)
  4.  *
  5.  * By Tuomas Luttinen & Aarno Syv鋘en (for Wiral Ltd) 
  6.  */
  7. #include <ctype.h>
  8. #include "xml_shared.h"
  9. #include "xml_definitions.h"
  10. #include <string.h>
  11. struct charset_t {
  12.     char *charset; 
  13.     char *nro;
  14.     unsigned char MIBenum;
  15. };
  16. charset_t character_sets[] = {
  17.     { "ISO", "8859-1", 4 },
  18.     { "ISO", "8859-2", 5 },
  19.     { "ISO", "8859-3", 6 },
  20.     { "ISO", "8859-4", 7 },
  21.     { "ISO", "8859-5", 8 },
  22.     { "ISO", "8859-6", 9 },
  23.     { "ISO", "8859-7", 10 },
  24.     { "ISO", "8859-8", 11 },
  25.     { "ISO", "8859-9", 12 },
  26.     { "UTF", "8", 106 },
  27.     { NULL }
  28. };
  29. /**************************************************************************** 
  30.  *
  31.  * Implementation of external functions
  32.  *
  33.  * set_charset - set the charset of the http headers into the document, if 
  34.  * it has no encoding set.
  35.  */
  36. void set_charset(Octstr *document, Octstr *charset)
  37. {
  38.     long gt = 0, enc = 0;
  39.     Octstr *encoding = NULL, *text = NULL, *temp = NULL;
  40.     if (octstr_len(charset) == 0)
  41. return;
  42.     encoding = octstr_create(" encoding");
  43.     enc = octstr_search(document, encoding, 0);
  44.     gt = octstr_search_char(document, '>', 0);
  45.     if (enc < 0 || enc > gt) {
  46. gt ++;
  47. text = octstr_copy(document, gt, octstr_len(document) - gt);
  48. if (charset_to_utf8(text, &temp, charset) >= 0) {
  49.     octstr_delete(document, gt, octstr_len(document) - gt);
  50.     octstr_append_data(document, octstr_get_cstr(temp), 
  51.        octstr_len(temp));
  52. }
  53. octstr_destroy(temp);
  54. octstr_destroy(text);
  55.     }
  56.     octstr_destroy(encoding);
  57. }
  58. /*
  59.  * only_blanks - checks if a text node contains only white space, when it can 
  60.  * be left out as a element content.
  61.  */
  62. int only_blanks(const char *text)
  63. {
  64.     int blank = 1;
  65.     int j=0;
  66.     int len = strlen(text);
  67.     while ((j<len) && blank) {
  68. blank = blank && isspace((int)text[j]);
  69. j++;
  70.     }
  71.  
  72.     return blank;
  73. }
  74. /*
  75.  * Parses the character set of the document. 
  76.  */
  77. int parse_charset(Octstr *charset)
  78. {
  79.     Octstr *number = NULL;
  80.     int i, j, cut = 0, ret = 0;
  81.     /* The charset might be in lower case, so... */
  82.     octstr_convert_range(charset, 0, octstr_len(charset), toupper);
  83.     /*
  84.      * The character set is handled in two parts to make things easier. 
  85.      * The cutting.
  86.      */
  87.     if ((cut = octstr_search_char(charset, '_', 0)) > 0) {
  88. number = octstr_copy(charset, cut + 1, 
  89.      (octstr_len(charset) - (cut + 1)));
  90. octstr_truncate(charset, cut);
  91.     } else if ((cut = octstr_search_char(charset, '-', 0)) > 0) {
  92. number = octstr_copy(charset, cut + 1, 
  93.      (octstr_len(charset) - (cut + 1)));
  94. octstr_truncate(charset, cut);
  95.     }
  96.     /* And table search. */
  97.     for (i = 0; character_sets[i].charset != NULL; i++)
  98. if (octstr_str_compare(charset, character_sets[i].charset) == 0) {
  99.     for (j = i; 
  100.  octstr_str_compare(charset, character_sets[j].charset) == 0; 
  101.  j++)
  102. if (octstr_str_compare(number, character_sets[j].nro) == 0) {
  103.     ret = character_sets[j].MIBenum;
  104.     break;
  105. }
  106.     break;
  107. }
  108.     /* UTF-8 is the default value */
  109.     if (character_sets[i].charset == NULL)
  110. ret = character_sets[i-1].MIBenum;
  111.     octstr_destroy(number);
  112.     return ret;
  113. }
  114. /*
  115.  * element_check_content - a helper function for parse_element for checking 
  116.  * if an element has content or attributes. Returns status bit for attributes 
  117.  * (0x80) and another for content (0x40) added into one octet.
  118.  */
  119. unsigned char element_check_content(xmlNodePtr node)
  120. {
  121.     unsigned char status_bits = 0x00;
  122.     if ((node->children != NULL) && 
  123. !((node->children->next == NULL) && 
  124.   (node->children->type == XML_TEXT_NODE) && 
  125.   (only_blanks(node->children->content))))
  126. status_bits = WBXML_CONTENT_BIT;
  127.     if (node->properties != NULL)
  128. status_bits = status_bits | WBXML_ATTR_BIT;
  129.     return status_bits;
  130. }
  131. /*
  132.  * Return the character sets supported by the WML compiler, as a List
  133.  * of Octstrs, where each string is the MIME identifier for one charset.
  134.  */
  135. List *wml_charsets(void)
  136. {
  137.     int i;
  138.     List *result;
  139.     Octstr *charset;
  140.     result = list_create();
  141.     for (i = 0; character_sets[i].charset != NULL; i++) {
  142.          charset = octstr_create(character_sets[i].charset);
  143.          octstr_append_char(charset, '-');
  144.          octstr_append(charset, octstr_imm(character_sets[i].nro));
  145.          list_append(result, charset);
  146.     }
  147.     return result;  
  148. }
  149. /*
  150.  * Functions working with simple binary data type (no string table). No 
  151.  * variables are present either. 
  152.  */
  153. simple_binary_t *simple_binary_create(void)
  154. {
  155.     simple_binary_t *binary;
  156.     binary = gw_malloc(sizeof(simple_binary_t));
  157.     
  158.     binary->wbxml_version = 0x00;
  159.     binary->public_id = 0x00;
  160.     binary->charset = 0x00;
  161.     binary->binary = octstr_create("");
  162.     return binary;
  163. }
  164. void simple_binary_destroy(simple_binary_t *binary)
  165. {
  166.     if (binary == NULL)
  167.         return;
  168.     octstr_destroy(binary->binary);
  169.     gw_free(binary);
  170. }
  171. /*
  172.  * Output the wbxml content field after field into octet string os. We add 
  173.  * string table length 0 (meaning no string table) before the content.
  174.  */
  175. void simple_binary_output(Octstr *os, simple_binary_t *binary)
  176. {
  177.     gw_assert(octstr_len(os) == 0);
  178.     octstr_format_append(os, "%c", binary->wbxml_version);
  179.     octstr_format_append(os, "%c", binary->public_id);
  180.     octstr_append_uintvar(os, binary->charset);
  181.     octstr_format_append(os, "%c", 0x00);
  182.     octstr_format_append(os, "%S", binary->binary);
  183. }
  184. void parse_end(simple_binary_t **binary)
  185. {
  186.     output_char(WBXML_END, binary);
  187. }
  188. void output_char(int byte, simple_binary_t **binary)
  189. {
  190.     octstr_append_char((**binary).binary, byte);
  191. }
  192. void parse_octet_string(Octstr *os, simple_binary_t **binary)
  193. {
  194.     output_octet_string(os, binary);
  195. }
  196. /*
  197.  * Add global tokens to the start and to the end of an inline string.
  198.  */ 
  199. void parse_inline_string(Octstr *temp, simple_binary_t **binary)
  200. {
  201.     Octstr *startos;   
  202.     octstr_insert(temp, startos = octstr_format("%c", WBXML_STR_I), 0);
  203.     octstr_destroy(startos);
  204.     octstr_format_append(temp, "%c", WBXML_STR_END);
  205.     parse_octet_string(temp, binary);
  206. }
  207. void output_octet_string(Octstr *os, simple_binary_t **sibxml)
  208. {
  209.     octstr_insert((*sibxml)->binary, os, octstr_len((*sibxml)->binary));
  210. }