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

手机WAP编程

开发平台:

WINDOWS

  1. /*
  2.  * decompile.c - A program to test the WML compiler. This tool was written
  3.  *               from the WBXML 1.2 and WML 1.1 specs.
  4.  *
  5.  * Author: Chris Wulff, Vanteon (cwulff@vanteon.com)
  6.  *
  7.  */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <memory.h>
  11. #include <string.h>
  12. #include "decompile.h"
  13. const WBXML_MB_U_INT32 ZERO_WBXML_MB_U_INT32 = {0,0,0,0};
  14. long dtd_id;
  15. #define INDENT_SIZE 4
  16. DTD_TYPE_LIST DTDTypeList[] =
  17. {
  18. {1, "UNKNOWN"},
  19. {2, "-//WAPFORUM//DTD WML 1.0//EN"n"
  20.  ""http://www.wapforum.org/DTD/wml.xml"},
  21. {3, "-//WAPFORUM//DTD WTA 1.0//EN"},
  22. {4, "-//WAPFORUM//DTD WML 1.1//EN"n"
  23.  ""http://www.wapforum.org/DTD/wml_1.1.xml"},
  24. {5, "-//WAPFORUM//DTD SI 1.0//EN"n"
  25.  ""http://www.wapforum.org/DTD/si.dtd"},
  26. {6, "-//WAPFORUM//DTD SL 1.0//EN"n"
  27.  ""http://www.wapforum.org/DTD/sl.dtd"},
  28. {7, "-//WAPFORUM//DTD CO 1.0//EN"},
  29. {8, "-//WAPFORUM//DTD CHANNEL 1.1//EN"},
  30. {9, "-//WAPFORUM//DTD WML 1.2//EN"n"
  31.  ""http://www.wapforum.org/DTD/wml12.dtd"},
  32. {0, NULL}
  33. };
  34. /**************************************
  35.  * DTD Public Type 4 (WML 1.1) Tables *
  36.  **************************************/
  37. CODEPAGE_TAG_NAME_LIST CodepageTagNames[] =
  38. {
  39. {4, "a",         0, 0x1c},
  40. {4, "anchor",    0, 0x22},
  41. {4, "access",    0, 0x23},
  42. {4, "b",         0, 0x24},
  43. {4, "big",       0, 0x25},
  44. {4, "br",        0, 0x26},
  45. {4, "card",      0, 0x27},
  46. {4, "do",        0, 0x28},
  47. {4, "em",        0, 0x29},
  48. {4, "fieldset",  0, 0x2a},
  49. {4, "go",        0, 0x2b},
  50. {4, "head",      0, 0x2c},
  51. {4, "i",         0, 0x2d},
  52. {4, "img",       0, 0x2e},
  53. {4, "input",     0, 0x2f},
  54. {4, "meta",      0, 0x30},
  55. {4, "noop",      0, 0x31},
  56. {4, "p",         0, 0x20},
  57. {4, "postfield", 0, 0x21},
  58. {4, "pre",       0, 0x1b},
  59. {4, "prev",      0, 0x32},
  60. {4, "onevent",   0, 0x33},
  61. {4, "optgroup",  0, 0x34},
  62. {4, "option",    0, 0x35},
  63. {4, "refresh",   0, 0x36},
  64. {4, "select",    0, 0x37},
  65. {4, "setvar",    0, 0x3e},
  66. {4, "small",     0, 0x38},
  67. {4, "strong",    0, 0x39},
  68. {4, "table",     0, 0x1f},
  69. {4, "td",        0, 0x1d},
  70. {4, "template",  0, 0x3b},
  71. {4, "timer",     0, 0x3c},
  72. {4, "tr",        0, 0x1e},
  73. {4, "u",         0, 0x3d},
  74. {4, "wml",       0, 0x3f},
  75. {6, "TAG_05",    1, 0x05},
  76. {6, "TAG_06",    1, 0x06},
  77. {6, "TAG_07",    1, 0x07},
  78. {0, NULL, 0, 0}
  79. };
  80. CODEPAGE_ATTRSTART_NAME_LIST CodepageAttrstartNames[] =
  81. {
  82. {4, "accept-charset",  NULL,                                0, 0x05},
  83. {4, "accesskey",       NULL,                                0, 0x5e},
  84. {4, "align",           NULL,                                0, 0x52},
  85. {4, "align",           "bottom",                            0, 0x06},
  86. {4, "align",           "center",                            0, 0x07},
  87. {4, "align",           "left",                              0, 0x08},
  88. {4, "align",           "middle",                            0, 0x09},
  89. {4, "align",           "right",                             0, 0x0a},
  90. {4, "align",           "top",                               0, 0x0b},
  91. {4, "alt",             NULL,                                0, 0x0c},
  92. {4, "class",           NULL,                                0, 0x54},
  93. {4, "columns",         NULL,                                0, 0x53},
  94. {4, "content",         NULL,                                0, 0x0d},
  95. {4, "content",         "application/vnd.wap.wmlc;charset=", 0, 0x5c},
  96. {4, "domain",          NULL,                                0, 0x0f},
  97. {4, "emptyok",         "false",                             0, 0x10},
  98. {4, "emptyok",         "true",                              0, 0x11},
  99. {4, "enctype",         NULL,                                0, 0x5f},
  100. {4, "enctype",         "application/x-www-form-urlencoded", 0, 0x60},
  101. {4, "enctype",         "multipart/form-data",               0, 0x61},
  102. {4, "format",          NULL,                                0, 0x12},
  103. {4, "forua",           "false",                             0, 0x56},
  104. {4, "forua",           "true",                              0, 0x57},
  105. {4, "height",          NULL,                                0, 0x13},
  106. {4, "href",            NULL,                                0, 0x4a},
  107. {4, "href",            "http://",                           0, 0x4b},
  108. {4, "href",            "https://",                          0, 0x4c},
  109. {4, "hspace",          NULL,                                0, 0x14},
  110. {4, "http-equiv",      NULL,                                0, 0x5a},
  111. {4, "http-equiv",      "Content-Type",                      0, 0x5b},
  112. {4, "http-equiv",      "Expires",                           0, 0x5d},
  113. {4, "id",              NULL,                                0, 0x55},
  114. {4, "ivalue",          NULL,                                0, 0x15},
  115. {4, "iname",           NULL,                                0, 0x16},
  116. {4, "label",           NULL,                                0, 0x18},
  117. {4, "localsrc",        NULL,                                0, 0x19},
  118. {4, "maxlength",       NULL,                                0, 0x1a},
  119. {4, "method",          "get",                               0, 0x1b},
  120. {4, "method",          "post",                              0, 0x1c},
  121. {4, "mode",            "nowrap",                            0, 0x1d},
  122. {4, "mode",            "wrap",                              0, 0x1e},
  123. {4, "multiple",        "false",                             0, 0x1f},
  124. {4, "multiple",        "true",                              0, 0x20},
  125. {4, "name",            NULL,                                0, 0x21},
  126. {4, "newcontext",      "false",                             0, 0x22},
  127. {4, "newcontext",      "true",                              0, 0x23},
  128. {4, "onenterbackward", NULL,                                0, 0x25},
  129. {4, "onenterforward",  NULL,                                0, 0x26},
  130. {4, "onpick",          NULL,                                0, 0x24},
  131. {4, "ontimer",         NULL,                                0, 0x27},
  132. {4, "optional",        "false",                             0, 0x28},
  133. {4, "optional",        "true",                              0, 0x29},
  134. {4, "path",            NULL,                                0, 0x2a},
  135. {4, "scheme",          NULL,                                0, 0x2e},
  136. {4, "sendreferer",     "false",                             0, 0x2f},
  137. {4, "sendreferer",     "true",                              0, 0x30},
  138. {4, "size",            NULL,                                0, 0x31},
  139. {4, "src",             NULL,                                0, 0x32},
  140. {4, "src",             "http://",                           0, 0x58},
  141. {4, "src",             "https://",                          0, 0x59},
  142. {4, "ordered",         "true",                              0, 0x33},
  143. {4, "ordered",         "false",                             0, 0x34},
  144. {4, "tabindex",        NULL,                                0, 0x35},
  145. {4, "title",           NULL,                                0, 0x36},
  146. {4, "type",            NULL,                                0, 0x37},
  147. {4, "type",            "accept",                            0, 0x38},
  148. {4, "type",            "delete",                            0, 0x39},
  149. {4, "type",            "help",                              0, 0x3a},
  150. {4, "type",            "password",                          0, 0x3b},
  151. {4, "type",            "onpick",                            0, 0x3c},
  152. {4, "type",            "onenterbackward",                   0, 0x3d},
  153. {4, "type",            "onenterforward",                    0, 0x3e},
  154. {4, "type",            "ontimer",                           0, 0x3f},
  155. {4, "type",            "options",                           0, 0x45},
  156. {4, "type",            "prev",                              0, 0x46},
  157. {4, "type",            "reset",                             0, 0x47},
  158. {4, "type",            "text",                              0, 0x48},
  159. {4, "type",            "vnd.",                              0, 0x49},
  160. {4, "value",           NULL,                                0, 0x4d},
  161. {4, "vspace",          NULL,                                0, 0x4e},
  162. {4, "width",           NULL,                                0, 0x4f},
  163. {4, "xml:lang",        NULL,                                0, 0x50},
  164. {6, "ATTR_06",         NULL,                                1, 0x06},
  165. {6, "ATTR_07",         NULL,                                1, 0x07},
  166. {6, "ATTR_08",         NULL,                                1, 0x08},
  167. {6, "ATTR_11",         NULL,                                1, 0x11},
  168. {6, "ATTR_12",         NULL,                                1, 0x12},
  169. {6, "ATTR_13",         NULL,                                1, 0x13},
  170. {6, "ATTR_14",         NULL,                                1, 0x14},
  171. {6, "ATTR_15",         NULL,                                1, 0x15},
  172. {6, "ATTR_21",         NULL,                                1, 0x21},
  173. {6, "ATTR_22",         NULL,                                1, 0x22},
  174. {6, "ATTR_23",         NULL,                                1, 0x23},
  175. {6, "ATTR_24",         NULL,                                1, 0x24},
  176. {6, "ATTR_28",         NULL,                                1, 0x28},
  177. {6, "ATTR_29",         NULL,                                1, 0x29},
  178. {6, "ATTR_45",         NULL,                                1, 0x45},
  179. {6, "ATTR_61",         NULL,                                1, 0x61},
  180. {6, "ATTR_62",         NULL,                                1, 0x62},
  181. {6, "ATTR_63",         NULL,                                1, 0x63},
  182. {6, "ATTR_64",         NULL,                                1, 0x64},
  183. {6, "ATTR_6A",         NULL,                                1, 0x6A},
  184. {6, "ATTR_6B",         NULL,                                1, 0x6B},
  185. {6, "ATTR_6C",         NULL,                                1, 0x6C},
  186. {6, "ATTR_70",         NULL,                                1, 0x70},
  187. {6, "ATTR_71",         NULL,                                1, 0x71},
  188. {6, "ATTR_73",         NULL,                                1, 0x73},
  189. {6, "ATTR_74",         NULL,                                1, 0x74},
  190. {0, NULL,              NULL,                                0, 0}
  191. };
  192. CODEPAGE_ATTRVALUE_NAME_LIST CodepageAttrvalueNames[] =
  193. {
  194. {4, ".com/",           0, 0x85},
  195. {4, ".edu/",           0, 0x86},
  196. {4, ".net/",           0, 0x87},
  197. {4, ".org/",           0, 0x88},
  198. {4, "accept",          0, 0x89},
  199. {4, "bottom",          0, 0x8a},
  200. {4, "clear",           0, 0x8b},
  201. {4, "delete",          0, 0x8c},
  202. {4, "help",            0, 0x8d},
  203. {4, "http://",         0, 0x8e},
  204. {4, "http://www.",     0, 0x8f},
  205. {4, "https://",        0, 0x90},
  206. {4, "https://www.",    0, 0x91},
  207. {4, "middle",          0, 0x93},
  208. {4, "nowrap",          0, 0x94},
  209. {4, "onenterbackward", 0, 0x96},
  210. {4, "onenterforward",  0, 0x97},
  211. {4, "onpick",          0, 0x95},
  212. {4, "ontimer",         0, 0x98},
  213. {4, "options",         0, 0x99},
  214. {4, "password",        0, 0x9a},
  215. {4, "reset",           0, 0x9b},
  216. {4, "text",            0, 0x9d},
  217. {4, "top",             0, 0x9e},
  218. {4, "unknown",         0, 0x9f},
  219. {4, "wrap",            0, 0xa0},
  220. {4, "www.",            0, 0xa1},
  221. {0, NULL, 0, 0}
  222. };
  223. /**************************
  224.  * Node Tree Construction *
  225.  **************************/
  226. /*
  227.  * Function: NewNode
  228.  *
  229.  * Description:
  230.  *
  231.  *  Allocate and initialize a new node. This links the new node
  232.  *  as the first child of the current node in the buffer. This causes
  233.  *  child nodes to be linked in reverse order. If there is no current
  234.  *  node, then the new node will be linked in as the first child at the
  235.  *  top of the tree.
  236.  *
  237.  * Parameters:
  238.  *
  239.  *  buffer - WBXML buffer to link the new node into
  240.  *  type   - Type of node to allocate
  241.  *
  242.  * Return value:
  243.  *
  244.  *  P_WBXML_NODE - A pointer to the newly allocated node.
  245.  *
  246.  */
  247. static P_WBXML_NODE NewNode(P_WBXML_INFO buffer, WBXML_NODE_TYPE type)
  248. {
  249. if (buffer)
  250. {
  251. P_WBXML_NODE newnode = malloc(sizeof(WBXML_NODE));
  252. if (newnode)
  253. {
  254. newnode->m_prev = NULL;
  255. newnode->m_child = NULL;
  256. if (buffer->m_curnode)
  257. {
  258. /* Insert this node as the first child of the current node */
  259. newnode->m_parent = buffer->m_curnode;
  260. newnode->m_next = buffer->m_curnode->m_child;
  261. if (buffer->m_curnode->m_child)
  262. {
  263. ((P_WBXML_NODE)buffer->m_curnode->m_child)->m_prev = newnode;
  264. }
  265. buffer->m_curnode->m_child = newnode;
  266. }
  267. else
  268. {
  269. /* Insert this node at the top of the tree */
  270. newnode->m_parent = NULL;
  271. newnode->m_next = buffer->m_tree;
  272. if (buffer->m_tree)
  273. {
  274. buffer->m_tree->m_prev = newnode;
  275. }
  276. buffer->m_tree = newnode;
  277. }
  278. newnode->m_page = buffer->m_curpage;
  279. newnode->m_type = type;
  280. newnode->m_data = NULL;
  281. }
  282. else
  283. {
  284. ParseError(ERR_NOT_ENOUGH_MEMORY);
  285. }
  286. return newnode;
  287. }
  288. else
  289. {
  290. ParseError(ERR_INTERNAL_BAD_PARAM);
  291. }
  292. return NULL;
  293. }
  294. /*
  295.  * Function: FreeNode
  296.  *
  297.  * Description:
  298.  *
  299.  *  Free a node, all its children and forward siblings.
  300.  *
  301.  * Parameters:
  302.  *
  303.  *  node - The node to free
  304.  *
  305.  */
  306. static void FreeNode(P_WBXML_NODE node)
  307. {
  308. if (node)
  309. {
  310. if (node->m_child)
  311. {
  312. FreeNode(node->m_child);
  313. }
  314. if (node->m_next)
  315. {
  316. FreeNode(node->m_next);
  317. }
  318. free(node);
  319. }
  320. }
  321. static void AddDTDNode(P_WBXML_INFO buffer, const WBXML_DTD_TYPE dtdnum, const WBXML_MB_U_INT32 index)
  322. {
  323. P_WBXML_NODE newnode = NewNode(buffer, NODE_DTD_TYPE);
  324. newnode->m_data = malloc(sizeof(DTD_NODE_DATA));
  325. memcpy( &( ((DTD_NODE_DATA*)newnode->m_data)->m_dtdnum ), &(dtdnum[0]), sizeof(WBXML_MB_U_INT32) );
  326. memcpy( &( ((DTD_NODE_DATA*)newnode->m_data)->m_index ), &(index[0]), sizeof(WBXML_MB_U_INT32) );
  327. dtd_id = (long) dtdnum[0];
  328. }
  329. static void AddStringTableNode(P_WBXML_INFO buffer, const P_WBXML_STRING_TABLE strings)
  330. {
  331. P_WBXML_NODE newnode = NewNode(buffer, NODE_STRING_TABLE);
  332. newnode->m_data = malloc(sizeof(WBXML_STRING_TABLE));
  333. memcpy( newnode->m_data, strings, sizeof(WBXML_STRING_TABLE) );
  334. }
  335. static void AddCodepageTagNode(P_WBXML_INFO buffer, WBXML_TAG tag)
  336. {
  337. P_WBXML_NODE newnode = NewNode(buffer, NODE_CODEPAGE_TAG);
  338. newnode->m_data = malloc(sizeof(WBXML_TAG));
  339. *((P_WBXML_TAG)newnode->m_data) = tag;
  340. }
  341. static void AddCodepageLiteralTagNode(P_WBXML_INFO buffer, WBXML_MB_U_INT32 index)
  342. {
  343. P_WBXML_NODE newnode = NewNode(buffer, NODE_CODEPAGE_LITERAL_TAG);
  344. newnode->m_data = malloc(sizeof(WBXML_MB_U_INT32));
  345. memcpy( ((P_WBXML_MB_U_INT32)newnode->m_data), &index, sizeof(WBXML_MB_U_INT32) );
  346. }
  347. static void AddAttrStartNode(P_WBXML_INFO buffer, WBXML_TAG tag)
  348. {
  349. P_WBXML_NODE newnode = NewNode(buffer, NODE_ATTRSTART);
  350. newnode->m_data = malloc(sizeof(WBXML_TAG));
  351. *((P_WBXML_TAG)newnode->m_data) = tag;
  352. }
  353. static void AddAttrStartLiteralNode(P_WBXML_INFO buffer, WBXML_MB_U_INT32 index)
  354. {
  355. P_WBXML_NODE newnode = NewNode(buffer, NODE_ATTRSTART_LITERAL);
  356. newnode->m_data = malloc(sizeof(WBXML_MB_U_INT32));
  357. memcpy( ((P_WBXML_MB_U_INT32)newnode->m_data), &index, sizeof(WBXML_MB_U_INT32) );
  358. }
  359. static void AddAttrValueNode(P_WBXML_INFO buffer, WBXML_TAG tag)
  360. {
  361. P_WBXML_NODE newnode = NewNode(buffer, NODE_ATTRVALUE);
  362. newnode->m_data = malloc(sizeof(WBXML_TAG));
  363. *((P_WBXML_TAG)newnode->m_data) = tag;
  364. }
  365. static void AddAttrEndNode(P_WBXML_INFO buffer)
  366. {
  367. P_WBXML_NODE newnode = NewNode(buffer, NODE_ATTREND);
  368. newnode->m_data = NULL;
  369. }
  370. static void AddStringNode(P_WBXML_INFO buffer, char* string)
  371. {
  372. P_WBXML_NODE newnode = NewNode(buffer, NODE_STRING);
  373. newnode->m_data = strdup(string);
  374. }
  375. static void AddVariableStringNode(P_WBXML_INFO buffer, char* string, WBXML_VARIABLE_TYPE type)
  376. {
  377. // TODO: add this node
  378. }
  379. static void AddVariableIndexNode(P_WBXML_INFO buffer, char* string, WBXML_VARIABLE_TYPE type)
  380. {
  381. // TODO: add this node
  382. }
  383. /****************
  384.  * Flow Control *
  385.  ****************/
  386. void Message(char* msg)
  387. {
  388.   printf("%sn", msg);
  389. }
  390. void ParseError(WBXML_PARSE_ERROR error)
  391. {
  392.   switch (error)
  393.   {
  394.     case ERR_END_OF_DATA:
  395.       Message("Input stream is incomplete (EOF).");
  396.       break;
  397.     case ERR_INTERNAL_BAD_PARAM:
  398.       Message("Internal error: Bad parameter.");
  399.       break;
  400. case ERR_TAG_NOT_FOUND:
  401.       Message("Tag not found.");
  402.       break;
  403. case ERR_FILE_NOT_FOUND:
  404.       Message("File not found.");
  405.       break;
  406. case ERR_FILE_NOT_READ:
  407.       Message("File read error.");
  408.       break;
  409. case ERR_NOT_ENOUGH_MEMORY:
  410.       Message("Not enough memory");
  411.       break;
  412.     default:
  413.       Message("Unknown error.");
  414.       break;
  415.   }
  416.   exit(error);
  417. }
  418. void ParseWarning(WBXML_PARSE_WARNING warning)
  419. {
  420.   switch (warning)
  421.   {
  422.     case WARN_FUTURE_EXPANSION_EXT_0:
  423.       Message("Token EXT_0 encountered. This token is reserved for future expansion.");
  424.       break;
  425.     case WARN_FUTURE_EXPANSION_EXT_1:
  426.       Message("Token EXT_1 encountered. This token is reserved for future expansion.");
  427.       break;
  428.     case WARN_FUTURE_EXPANSION_EXT_2:
  429.       Message("Token EXT_2 encountered. This token is reserved for future expansion.");
  430.       break;
  431.     default:
  432.       Message("Unknown warning.");
  433.       break;
  434.   }
  435. }
  436. WBXML_LENGTH BytesLeft(P_WBXML_INFO buffer)
  437. {
  438.   if (buffer)
  439.   {
  440.     WBXML_LENGTH bytesRead = (buffer->m_curpos - buffer->m_start);
  441.     if (bytesRead >= buffer->m_length)
  442.     {
  443.       return 0;
  444.     }
  445.     else
  446.     {
  447.       return (buffer->m_length - bytesRead);
  448.     }
  449.   }
  450.   else
  451.   {
  452.     ParseError(ERR_INTERNAL_BAD_PARAM);
  453.   }
  454.   return 0;
  455. }
  456. BOOL IsTag(P_WBXML_INFO buffer, WBXML_TAG tag)
  457. {
  458.   BOOL result = FALSE;
  459.   if (buffer)
  460.   {
  461.     if (BytesLeft(buffer) >= sizeof(WBXML_TAG))
  462.     {
  463.       result = ((*((WBXML_TAG*) buffer->m_curpos)) == tag);
  464.     }
  465.     else
  466.     {
  467. /* No more data, so nope, not this tag */
  468.       result = FALSE;
  469.     }
  470.   }
  471.   else
  472.   {
  473.     ParseError(ERR_INTERNAL_BAD_PARAM);
  474.   }
  475.   return result;
  476. }
  477. BOOL IsCodepageTag(P_WBXML_INFO buffer, CP_TAG_TYPE type)
  478. {
  479. WBXML_U_INT8 result = *(buffer->m_curpos);
  480. /* NOTE THAT THESE ARE NOT UNIQUE! */
  481. switch (type)
  482. {
  483. case CP_TAG_TAG:
  484. return TRUE;
  485. case CP_TAG_ATTRSTART:
  486. return ((result & 0x80) != 0x80);
  487. case CP_TAG_ATTRVALUE:
  488. return ((result & 0x80) == 0x80);
  489. default:
  490. return FALSE;
  491. }
  492. }
  493. BOOL Is_attrValue  (P_WBXML_INFO buffer)
  494. {
  495. WBXML_INFO tmpbuffer;
  496. memcpy(&tmpbuffer, buffer, sizeof(WBXML_INFO));
  497. tmpbuffer.m_curpos += SWITCHPAGE_SIZE;
  498. return ((Is_switchPage(buffer) && IsCodepageTag(&tmpbuffer, CP_TAG_ATTRVALUE)) ||
  499.     IsCodepageTag(buffer, CP_TAG_ATTRVALUE) ||
  500. Is_string(buffer) ||
  501. Is_extension(buffer) ||
  502. Is_entity(buffer) ||
  503. Is_pi(buffer) ||
  504. Is_opaque(buffer));
  505. }
  506. BOOL Is_extension  (P_WBXML_INFO buffer)
  507. {
  508. WBXML_INFO tmpbuffer;
  509. memcpy(&tmpbuffer, buffer, sizeof(WBXML_INFO));
  510. tmpbuffer.m_curpos += SWITCHPAGE_SIZE;
  511. return ((Is_switchPage(buffer) &&
  512.      (IsTag(&tmpbuffer, TAG_EXT_0) ||
  513.       IsTag(&tmpbuffer, TAG_EXT_1) ||
  514.       IsTag(&tmpbuffer, TAG_EXT_2) ||
  515.       IsTag(&tmpbuffer, TAG_EXT_T_0) ||
  516.       IsTag(&tmpbuffer, TAG_EXT_T_1) ||
  517.       IsTag(&tmpbuffer, TAG_EXT_T_2) ||
  518.       IsTag(&tmpbuffer, TAG_EXT_I_0) ||
  519.       IsTag(&tmpbuffer, TAG_EXT_I_1) ||
  520.       IsTag(&tmpbuffer, TAG_EXT_I_2))) ||
  521.     (IsTag(buffer, TAG_EXT_0) ||
  522.      IsTag(buffer, TAG_EXT_1) ||
  523.      IsTag(buffer, TAG_EXT_2) ||
  524.      IsTag(buffer, TAG_EXT_T_0) ||
  525.      IsTag(buffer, TAG_EXT_T_1) ||
  526.      IsTag(buffer, TAG_EXT_T_2) ||
  527.      IsTag(buffer, TAG_EXT_I_0) ||
  528.      IsTag(buffer, TAG_EXT_I_1) ||
  529.      IsTag(buffer, TAG_EXT_I_2)));
  530. }
  531. BOOL Is_string     (P_WBXML_INFO buffer)
  532. {
  533. return (Is_inline(buffer) ||
  534.     Is_tableref(buffer));
  535. }
  536. BOOL Is_switchPage (P_WBXML_INFO buffer)
  537. {
  538. return IsTag(buffer, TAG_SWITCH_PAGE);
  539. }
  540. BOOL Is_inline     (P_WBXML_INFO buffer)
  541. {
  542. return IsTag(buffer, TAG_STR_I);
  543. }
  544. BOOL Is_tableref   (P_WBXML_INFO buffer)
  545. {
  546. return IsTag(buffer, TAG_STR_T);
  547. }
  548. BOOL Is_entity     (P_WBXML_INFO buffer)
  549. {
  550. return IsTag(buffer, TAG_ENTITY);
  551. }
  552. BOOL Is_pi         (P_WBXML_INFO buffer)
  553. {
  554. return IsTag(buffer, TAG_PI);
  555. }
  556. BOOL Is_opaque     (P_WBXML_INFO buffer)
  557. {
  558. return IsTag(buffer, TAG_OPAQUE);
  559. }
  560. BOOL Is_zero(P_WBXML_INFO buffer)
  561. {
  562.   BOOL result = FALSE;
  563.   if (buffer) 
  564.   {
  565.     if (BytesLeft(buffer) >= 1) 
  566.     {
  567.       result = ((*buffer->m_curpos) == 0);
  568.     }
  569.     else
  570.     {
  571.       ParseError(ERR_END_OF_DATA);
  572.     }
  573.   }
  574.   else
  575.   {
  576.     ParseError(ERR_INTERNAL_BAD_PARAM);
  577.   }
  578.   return result;
  579. }
  580. /***********************
  581.  * Basic Type Decoders *
  582.  ***********************/
  583. void Read_u_int8(P_WBXML_INFO buffer, P_WBXML_U_INT8 result)
  584. {
  585.   if (buffer && result)
  586.   {
  587.     if (BytesLeft(buffer) >= 1) 
  588.     {
  589.       *result = *(buffer->m_curpos);
  590.       (buffer->m_curpos)++;
  591.     }
  592.     else
  593.     {
  594.       ParseError(ERR_END_OF_DATA);
  595.     }
  596.   }
  597.   else
  598.   {
  599.     ParseError(ERR_INTERNAL_BAD_PARAM);
  600.   }
  601. }
  602. void Read_mb_u_int32(P_WBXML_INFO buffer, P_WBXML_MB_U_INT32 result)
  603. {
  604.   if (buffer && result)
  605.   {
  606.     int i;
  607.     for (i = 0; i < MAX_MB_U_INT32_BYTES; i++)
  608.     {
  609.       if (BytesLeft(buffer) >= 1)
  610.       {
  611.         (*result)[i] = *(buffer->m_curpos);
  612.         (buffer->m_curpos)++;
  613.         if ( !( (*result)[i] & 0x80 ) )
  614.           break;
  615.       }
  616.       else
  617.       {
  618.         ParseError(ERR_END_OF_DATA);
  619.       }
  620.     }
  621.   }
  622.   else
  623.   {
  624.     ParseError(ERR_INTERNAL_BAD_PARAM);
  625.   }
  626. }
  627. void Read_bytes(P_WBXML_INFO buffer, WBXML_LENGTH length, P_WBXML_BYTES result)
  628. {
  629.   if (buffer && result)
  630.   {
  631.     if (BytesLeft(buffer) >= length) 
  632.     {
  633.       *result = (WBXML_BYTES) malloc(length*sizeof(unsigned char));
  634.       memcpy(*result, buffer->m_curpos, length);
  635.       buffer->m_curpos += length;
  636.     }
  637.     else
  638.     {
  639.       ParseError(ERR_END_OF_DATA);
  640.     }
  641.   }
  642.   else
  643.   {
  644.     ParseError(ERR_INTERNAL_BAD_PARAM);
  645.   }
  646. }
  647. void ReadFixedTag(P_WBXML_INFO buffer, WBXML_TAG tag)
  648. {
  649.   if (buffer)
  650.   {
  651.     if (BytesLeft(buffer) >= sizeof(WBXML_TAG))
  652.     {
  653.       if ((*((WBXML_TAG*) buffer->m_curpos)) == tag)
  654.       {
  655.         buffer->m_curpos += sizeof(WBXML_TAG);
  656.       }
  657.       else
  658.       {
  659.         ParseError(ERR_TAG_NOT_FOUND);
  660.       }
  661.     }
  662.     else
  663.     {
  664.       ParseError(ERR_END_OF_DATA);
  665.     }
  666.   }
  667.   else
  668.   {
  669.     ParseError(ERR_INTERNAL_BAD_PARAM);
  670.   }
  671. }
  672. WBXML_TAG ReadCodepageTag (P_WBXML_INFO buffer, CP_TAG_TYPE type)
  673. {
  674.   WBXML_TAG tag = 0;
  675.   if (buffer)
  676.   {
  677.     if (BytesLeft(buffer) >= sizeof(WBXML_TAG))
  678.     {
  679.       tag = *((WBXML_TAG*) buffer->m_curpos);
  680.   switch (type)
  681.   {
  682.     case CP_TAG_TAG:
  683.   buffer->m_curpos += sizeof(WBXML_TAG);
  684.   break;
  685. case CP_TAG_ATTRSTART:
  686.   if ((tag & 0x80) != 0x80)
  687.   {
  688.     buffer->m_curpos += sizeof(WBXML_TAG);
  689.   }
  690.   else
  691.   {
  692.   ParseError(ERR_TAG_NOT_FOUND);
  693.   }
  694.   break;
  695. case CP_TAG_ATTRVALUE:
  696.   if ((tag & 0x80) == 0x80)
  697.   {
  698.     buffer->m_curpos += sizeof(WBXML_TAG);
  699.   }
  700.   else
  701.   {
  702.   ParseError(ERR_TAG_NOT_FOUND);
  703.   }
  704.   break;
  705. default:
  706.   ParseError(ERR_TAG_NOT_FOUND);
  707.   break;
  708.       }
  709.     }
  710.     else
  711.     {
  712.       ParseError(ERR_END_OF_DATA);
  713.     }
  714.   }
  715.   else
  716.   {
  717.     ParseError(ERR_INTERNAL_BAD_PARAM);
  718.   }
  719.   return tag;
  720. }
  721. /**************************
  722.  * Basic Type Conversions *
  723.  **************************/
  724. long mb_u_int32_to_long(P_WBXML_MB_U_INT32 value)
  725. {
  726.   long result = 0;
  727.   if (value)
  728.   {
  729.     int i;
  730.     for (i = 0; i < MAX_MB_U_INT32_BYTES; i++)
  731.     {
  732.       result <<= 7;
  733.       result |= ((*value)[i] & 0x7f);
  734.       if ( !( (*value)[i] & 0x80 ) )
  735.         break;
  736.     }
  737.   }
  738.   else
  739.   {
  740.     ParseError(ERR_INTERNAL_BAD_PARAM);
  741.   }
  742.   return result;
  743. }
  744. static void OutputEncodedString(const unsigned char* str)
  745. {
  746. /* Work our way down the string looking for illegal chars */
  747. while (*str != 0)
  748. {
  749. if ((*str < 0x20) || (*str > 0x7F))
  750. {
  751. /* Out of range... encode */
  752. printf("&#x%02x;", *str);
  753. }
  754. else
  755. {
  756. switch (*str)
  757. {
  758. case '<':
  759. case '>':
  760. case '&':
  761. case ''':
  762. case '"':
  763. /* Special symbol... encode */
  764. printf("&#x%2x", *str);
  765. break;
  766. default:
  767. printf("%c", *str);
  768. break;
  769. }
  770. }
  771. str++;
  772. }
  773. }
  774. /*******************************
  775.  * Document Structure Decoders *
  776.  *******************************/
  777. void Read_start      (P_WBXML_INFO buffer)
  778. {
  779.   Read_version(buffer);
  780.   Read_publicid(buffer);
  781.   Read_charset(buffer);
  782.   Read_strtbl(buffer);
  783.   Read_body(buffer);
  784. }
  785. void Read_strtbl     (P_WBXML_INFO buffer)
  786. {
  787.   WBXML_STRING_TABLE result;
  788.   Read_mb_u_int32(buffer, &(result.m_length));
  789.   Read_bytes(buffer, mb_u_int32_to_long(&(result.m_length)), &(result.m_strings));
  790.   AddStringTableNode(buffer, &result);
  791. }
  792. void Read_body       (P_WBXML_INFO buffer)
  793. {
  794.   while (Is_pi(buffer))
  795.   {
  796.     Read_pi(buffer);
  797.   }
  798.   Read_element(buffer);
  799.   while (Is_pi(buffer))
  800.   {
  801.     Read_pi(buffer);
  802.   }
  803. }
  804. void Read_element    (P_WBXML_INFO buffer)
  805. {
  806.   WBXML_TAG stagvalue = 0;
  807.   if (Is_switchPage(buffer))
  808.   {
  809.     Read_switchPage(buffer);
  810.   }
  811.   stagvalue = Read_stag(buffer);
  812.   /* move the current node down to this one in the tree */
  813.   if (buffer->m_curnode)
  814.   buffer->m_curnode = buffer->m_curnode->m_child;
  815.   else buffer->m_curnode = buffer->m_tree;
  816.   if ((stagvalue & CODEPAGE_TAG_HAS_ATTRS) == CODEPAGE_TAG_HAS_ATTRS)
  817.   {
  818.     do
  819.     {
  820.       Read_attribute(buffer);
  821.     } while (!IsTag(buffer, TAG_END));
  822.     ReadFixedTag(buffer, TAG_END);
  823. AddAttrEndNode(buffer);
  824.   }
  825.   if ((stagvalue & CODEPAGE_TAG_HAS_CONTENT) == CODEPAGE_TAG_HAS_CONTENT)
  826.   {
  827.     while (!IsTag(buffer, TAG_END))
  828. {
  829.       Read_content(buffer);
  830. }
  831.     ReadFixedTag(buffer, TAG_END);
  832.   }
  833.   /* move the current node back up one */
  834.   buffer->m_curnode = buffer->m_curnode->m_parent;
  835. }
  836. void Read_content    (P_WBXML_INFO buffer)
  837. {
  838. if (Is_string(buffer))
  839. {
  840. Read_string(buffer);
  841. }
  842. else if (Is_extension(buffer))
  843. {
  844. Read_extension(buffer);
  845. }
  846. else if (Is_entity(buffer))
  847. {
  848. Read_entity(buffer);
  849. }
  850. else if (Is_pi(buffer))
  851. {
  852. Read_pi(buffer);
  853. }
  854. else if (Is_opaque(buffer))
  855. {
  856. Read_opaque(buffer);
  857. }
  858. else
  859. {
  860. /* Assume it is an element */
  861. Read_element(buffer);
  862. }
  863. }
  864. WBXML_TAG Read_stag       (P_WBXML_INFO buffer)
  865. {
  866. if (IsCodepageTag(buffer, CP_TAG_TAG))
  867. {
  868. WBXML_TAG tag = ReadCodepageTag(buffer, CP_TAG_TAG);
  869. AddCodepageTagNode(buffer, tag);
  870. return tag;
  871. }
  872. else if (IsTag(buffer, TAG_LITERAL))
  873. {
  874. WBXML_MB_U_INT32 index;
  875. ReadFixedTag(buffer, TAG_LITERAL);
  876. Read_index(buffer, &index);
  877. AddCodepageLiteralTagNode(buffer, index);
  878. }
  879. else
  880. {
  881. ParseError(ERR_TAG_NOT_FOUND);
  882. }
  883. return 0;
  884. }
  885. void Read_attribute  (P_WBXML_INFO buffer)
  886. {
  887. Read_attrStart(buffer);
  888. while (Is_attrValue(buffer))
  889. {
  890. Read_attrValue(buffer);
  891. }
  892. }
  893. void Read_attrStart  (P_WBXML_INFO buffer)
  894. {
  895.   if (Is_switchPage(buffer))
  896.   {
  897. WBXML_TAG tag;
  898.     Read_switchPage(buffer);
  899.     tag = ReadCodepageTag(buffer, CP_TAG_ATTRSTART);
  900. AddAttrStartNode(buffer, tag);
  901.   }
  902.   else if (IsCodepageTag(buffer, CP_TAG_ATTRSTART))
  903.   {
  904. WBXML_TAG tag;
  905.     tag = ReadCodepageTag(buffer, CP_TAG_ATTRSTART);
  906. AddAttrStartNode(buffer, tag);
  907.   }
  908.   else if (IsTag(buffer, TAG_LITERAL))
  909.   {
  910.     WBXML_MB_U_INT32 index;
  911.     ReadFixedTag(buffer, TAG_LITERAL);
  912.     Read_index(buffer, &index);
  913. AddAttrStartLiteralNode(buffer, index);
  914.   }
  915.   else
  916.   {
  917.     ParseError(ERR_TAG_NOT_FOUND);
  918.   }
  919. }
  920. void Read_attrValue  (P_WBXML_INFO buffer)
  921. {
  922.   if (Is_switchPage(buffer))
  923.   {
  924. WBXML_TAG tag;
  925.     Read_switchPage(buffer);
  926.     tag = ReadCodepageTag(buffer, CP_TAG_ATTRVALUE);
  927. AddAttrValueNode(buffer, tag);
  928.   }
  929.   else if (IsCodepageTag(buffer, CP_TAG_ATTRVALUE))
  930.   {
  931. WBXML_TAG tag;
  932.     tag = ReadCodepageTag(buffer, CP_TAG_ATTRVALUE);
  933. AddAttrValueNode(buffer, tag);
  934.   }
  935.   else if (Is_string(buffer))
  936.   {
  937.     Read_string(buffer);
  938.   }
  939.   else if (Is_extension(buffer))
  940.   {
  941.     Read_extension(buffer);
  942.   }
  943.   else if (Is_entity(buffer))
  944.   {
  945.     Read_entity(buffer);
  946.   }
  947.   else if (Is_opaque(buffer))
  948.   {
  949.     Read_opaque(buffer);
  950.   }
  951.   else
  952.   {
  953.     ParseError(ERR_TAG_NOT_FOUND);
  954.   }
  955. }
  956. void Read_extension  (P_WBXML_INFO buffer)
  957. {
  958. if (Is_switchPage(buffer))
  959. {
  960. Read_switchPage(buffer);
  961. }
  962. if (IsTag(buffer, TAG_EXT_I_0))
  963. {
  964. char* str = NULL;
  965. ReadFixedTag(buffer, TAG_EXT_I_0);
  966. Read_termstr_rtn(buffer, &str);
  967. AddVariableStringNode(buffer, str, VAR_ESCAPED); 
  968. }
  969. else if (IsTag(buffer, TAG_EXT_I_1))
  970. {
  971. char* str = NULL;
  972. ReadFixedTag(buffer, TAG_EXT_I_1);
  973. Read_termstr_rtn(buffer, &str);
  974. AddVariableStringNode(buffer, str, VAR_UNESCAPED); 
  975. }
  976. else if (IsTag(buffer, TAG_EXT_I_2))
  977. {
  978. char* str = NULL;
  979. ReadFixedTag(buffer, TAG_EXT_I_2);
  980. Read_termstr_rtn(buffer, &str);
  981. AddVariableStringNode(buffer, str, VAR_UNCHANGED); 
  982. }
  983. else if (IsTag(buffer, TAG_EXT_T_0))
  984. {
  985. WBXML_MB_U_INT32 index;
  986. ReadFixedTag(buffer, TAG_EXT_T_0);
  987. Read_index(buffer, &index);
  988. AddVariableIndexNode(buffer, index, VAR_ESCAPED);
  989. }
  990. else if (IsTag(buffer, TAG_EXT_T_1))
  991. {
  992. WBXML_MB_U_INT32 index;
  993. ReadFixedTag(buffer, TAG_EXT_T_1);
  994. Read_index(buffer, &index);
  995. AddVariableIndexNode(buffer, index, VAR_UNESCAPED);
  996. }
  997. else if (IsTag(buffer, TAG_EXT_T_2))
  998. {
  999. WBXML_MB_U_INT32 index;
  1000. ReadFixedTag(buffer, TAG_EXT_T_2);
  1001. Read_index(buffer, &index);
  1002. AddVariableIndexNode(buffer, index, VAR_UNCHANGED);
  1003. }
  1004. else if (IsTag(buffer, TAG_EXT_0))
  1005. {
  1006. ReadFixedTag(buffer, TAG_EXT_0);
  1007. ParseWarning(WARN_FUTURE_EXPANSION_EXT_0);
  1008. }
  1009. else if (IsTag(buffer, TAG_EXT_1))
  1010. {
  1011. ReadFixedTag(buffer, TAG_EXT_1);
  1012. ParseWarning(WARN_FUTURE_EXPANSION_EXT_1);
  1013. }
  1014. else if (IsTag(buffer, TAG_EXT_2))
  1015. {
  1016. ReadFixedTag(buffer, TAG_EXT_2);
  1017. ParseWarning(WARN_FUTURE_EXPANSION_EXT_2);
  1018. }
  1019. else
  1020. {
  1021. ParseError(ERR_TAG_NOT_FOUND);
  1022. }
  1023. }
  1024. void Read_string     (P_WBXML_INFO buffer)
  1025. {
  1026. if (Is_inline(buffer))
  1027. {
  1028. Read_inline(buffer);
  1029. }
  1030. else if (Is_tableref(buffer))
  1031. {
  1032. Read_tableref(buffer);
  1033. }
  1034. else
  1035. {
  1036. ParseError(ERR_TAG_NOT_FOUND);
  1037. }
  1038. }
  1039. void Read_switchPage (P_WBXML_INFO buffer)
  1040. {
  1041.   WBXML_U_INT8 pageindex;
  1042.   ReadFixedTag(buffer, TAG_SWITCH_PAGE);
  1043.   Read_pageindex(buffer, &pageindex);
  1044.   /* Use the new codepage */
  1045.   buffer->m_curpage = pageindex;
  1046. }
  1047. void Read_inline     (P_WBXML_INFO buffer)
  1048. {
  1049. ReadFixedTag(buffer, TAG_STR_I);
  1050. Read_termstr(buffer);
  1051. }
  1052. void Read_tableref   (P_WBXML_INFO buffer)
  1053. {
  1054.   WBXML_MB_U_INT32 index;
  1055.   ReadFixedTag(buffer, TAG_STR_T);
  1056.   Read_index(buffer, &index);
  1057. }
  1058. void Read_entity     (P_WBXML_INFO buffer)
  1059. {
  1060. ReadFixedTag(buffer, TAG_ENTITY);
  1061. Read_entcode(buffer);
  1062. }
  1063. void Read_entcode    (P_WBXML_INFO buffer)
  1064. {
  1065. WBXML_MB_U_INT32 result;
  1066. Read_mb_u_int32(buffer, &result);
  1067. }
  1068. void Read_pi         (P_WBXML_INFO buffer)
  1069. {
  1070.   ReadFixedTag(buffer, TAG_PI);
  1071.   Read_attrStart(buffer);
  1072.   
  1073.   while (Is_attrValue(buffer))
  1074.   {
  1075.     Read_attrValue(buffer);
  1076.   }
  1077.   ReadFixedTag(buffer, TAG_END);
  1078. }
  1079. void Read_opaque     (P_WBXML_INFO buffer)
  1080. {
  1081.   WBXML_MB_U_INT32 length;
  1082.   WBXML_BYTES      data;
  1083.   ReadFixedTag(buffer, TAG_OPAQUE);
  1084.   Read_length(buffer, &length);
  1085.   Read_bytes(buffer, mb_u_int32_to_long(&length), &data);
  1086. }
  1087. void Read_version    (P_WBXML_INFO buffer)
  1088. {
  1089.   WBXML_U_INT8 result;
  1090.   Read_u_int8(buffer, &result);
  1091. }
  1092. void Read_publicid   (P_WBXML_INFO buffer)
  1093. {
  1094.   if (Is_zero(buffer))
  1095.   {
  1096.     WBXML_MB_U_INT32 index;
  1097.     Read_index(buffer, &index);
  1098. AddDTDNode(buffer, ZERO_WBXML_MB_U_INT32, index);
  1099.   }
  1100.   else
  1101.   {
  1102.     WBXML_MB_U_INT32 result;
  1103.     Read_mb_u_int32(buffer, &result);
  1104. AddDTDNode(buffer, result, ZERO_WBXML_MB_U_INT32);
  1105.   }
  1106. }
  1107. void Read_charset    (P_WBXML_INFO buffer)
  1108. {
  1109.   WBXML_MB_U_INT32 result;
  1110.   Read_mb_u_int32(buffer, &result);
  1111. }
  1112. void Read_termstr_rtn(P_WBXML_INFO buffer, char** result)
  1113. {
  1114. #define STRING_BLOCK_SIZE 256
  1115. int buflen = STRING_BLOCK_SIZE;
  1116. char* strbuf = (char*) malloc(buflen);
  1117. BOOL doubled = FALSE;
  1118. int i = 0;
  1119. if (!result)
  1120. ParseError(ERR_INTERNAL_BAD_PARAM);
  1121. while ( (BytesLeft(buffer) >= 1) && (*(buffer->m_curpos) != 0) )
  1122. {
  1123. if (i>=buflen)
  1124. {
  1125. buflen += STRING_BLOCK_SIZE;
  1126. strbuf = realloc(strbuf, buflen);
  1127. }
  1128. if (*(buffer->m_curpos) != '$' || doubled == TRUE)
  1129. {
  1130. strbuf[i] = *(buffer->m_curpos);
  1131. buffer->m_curpos++;
  1132. i++;
  1133. if (doubled == TRUE)
  1134. doubled = FALSE;
  1135. }
  1136. else
  1137. {
  1138. strbuf[i] = *(buffer->m_curpos);
  1139. i++;
  1140. doubled = TRUE;
  1141. }
  1142. }
  1143. strbuf[i] = 0;
  1144. buffer->m_curpos++;
  1145. if (*result)
  1146. free(*result);
  1147. *result = strbuf;
  1148. }
  1149. void Read_termstr    (P_WBXML_INFO buffer)
  1150. {
  1151. char* strbuf = NULL;
  1152. Read_termstr_rtn(buffer, &strbuf);
  1153. AddStringNode(buffer, strbuf);
  1154. free(strbuf);
  1155. }
  1156. void Read_index      (P_WBXML_INFO buffer, P_WBXML_MB_U_INT32 result)
  1157. {
  1158.   Read_mb_u_int32(buffer, result);
  1159. }
  1160. void Read_length     (P_WBXML_INFO buffer, P_WBXML_MB_U_INT32 result)
  1161. {
  1162.   Read_mb_u_int32(buffer, result);
  1163. }
  1164. void Read_zero       (P_WBXML_INFO buffer)
  1165. {
  1166.   WBXML_U_INT8 result;
  1167.   Read_u_int8(buffer, &result);
  1168.   if (result != (WBXML_U_INT8) 0)
  1169.   {
  1170.     ParseError(ERR_TAG_NOT_FOUND);
  1171.   }
  1172. }
  1173. void Read_pageindex  (P_WBXML_INFO buffer, P_WBXML_U_INT8 result)
  1174. {
  1175.   Read_u_int8(buffer, result);
  1176. }
  1177. static void Init(P_WBXML_INFO buffer)
  1178. {
  1179. buffer->m_start = NULL;
  1180. buffer->m_curpos = NULL;
  1181. buffer->m_length = 0;
  1182. buffer->m_tree = NULL;
  1183. buffer->m_curnode = NULL;
  1184. buffer->m_curpage = 0;
  1185. }
  1186. static size_t BufferLength(P_WBXML_INFO buffer)
  1187. {
  1188. size_t ret;
  1189. while (buffer->m_curpos != '')
  1190. buffer->m_curpos++;
  1191. ret = buffer->m_curpos - buffer->m_start;
  1192. buffer->m_curpos = buffer->m_start;
  1193. return ret;
  1194. }
  1195. static void Free(P_WBXML_INFO buffer)
  1196. {
  1197. if (buffer->m_start)
  1198. {
  1199. free(buffer->m_start);
  1200. buffer->m_start = NULL;
  1201. }
  1202. buffer->m_curpos = NULL;
  1203. buffer->m_length = 0;
  1204. FreeNode(buffer->m_tree);
  1205. buffer->m_tree = NULL;
  1206. }
  1207. static long FileSize(FILE* file)
  1208. {
  1209. long curpos = ftell(file);
  1210. long endpos;
  1211. fseek(file, 0, SEEK_END);
  1212. endpos = ftell(file);
  1213. fseek(file, curpos, SEEK_SET);
  1214. return endpos;
  1215. }
  1216. static void ReadBinary(P_WBXML_INFO buffer, FILE* file)
  1217. {
  1218. char buf[4096];
  1219. int m = 1;
  1220. long n;
  1221. if (buffer && file)
  1222. {
  1223. if (file != stdin)
  1224. {
  1225. buffer->m_length = FileSize(file);
  1226. buffer->m_start = (P_WBXML) malloc(buffer->m_length);
  1227. buffer->m_curpos = buffer->m_start;
  1228. if (!buffer->m_start)
  1229. {
  1230. fclose(file);
  1231. ParseError(ERR_NOT_ENOUGH_MEMORY);
  1232. }
  1233. if (fread(buffer->m_start, 1, buffer->m_length, file) != buffer->m_length)
  1234. {
  1235. fclose(file);
  1236. ParseError(ERR_FILE_NOT_READ);
  1237. }
  1238. else
  1239. {
  1240. fclose(file);
  1241. }
  1242. }
  1243. else
  1244. {
  1245. while ((n = fread(buf, 1, sizeof(buf), file)) > 0)
  1246. {
  1247. buffer->m_start = (P_WBXML) realloc(buffer->m_start, sizeof(buf) * m);
  1248. memcpy(buffer->m_start + (sizeof(buf) * (m - 1)), buf, sizeof(buf));
  1249. m++;
  1250. }
  1251. buffer->m_length = BufferLength(buffer);
  1252. buffer->m_curpos = buffer->m_start;
  1253. }
  1254. }
  1255. else
  1256. {
  1257. ParseError(ERR_INTERNAL_BAD_PARAM);
  1258. }
  1259. }
  1260. static const char* DTDTypeName(long dtdnum)
  1261. {
  1262. int i = 0;
  1263. /* Search the DTD list for a match */
  1264. while (DTDTypeList[i].m_name)
  1265. {
  1266. if (DTDTypeList[i].m_id == dtdnum)
  1267. {
  1268. break;
  1269. }
  1270. i++;
  1271. }
  1272. return DTDTypeList[i].m_name;
  1273. }
  1274. static const char* CodepageTagName(WBXML_CODEPAGE page, WBXML_TAG tag)
  1275. {
  1276. int i = 0;
  1277. /* Strip flags off of the tag */
  1278. tag = (WBXML_TAG) (tag & CODEPAGE_TAG_MASK);
  1279. /* Search the tag list for a match */
  1280. while (CodepageTagNames[i].m_name)
  1281. {
  1282. if ((CodepageTagNames[i].m_dtd_id == dtd_id) &&
  1283. (CodepageTagNames[i].m_page == page) &&
  1284. (CodepageTagNames[i].m_tag == tag))
  1285. {
  1286. break;
  1287. }
  1288. i++;
  1289. }
  1290. return CodepageTagNames[i].m_name;
  1291. }
  1292. static const char* CodepageAttrstartName(WBXML_CODEPAGE page, WBXML_TAG tag, char** value)
  1293. {
  1294. int i = 0;
  1295. /* Check Parameters */
  1296. if (!value)
  1297. {
  1298. ParseError(ERR_INTERNAL_BAD_PARAM);
  1299. }
  1300. /* Search the tag list for a match */
  1301. while (CodepageAttrstartNames[i].m_name)
  1302. {
  1303. if ((CodepageAttrstartNames[i].m_dtd_id == dtd_id) &&
  1304. (CodepageAttrstartNames[i].m_page == page) &&
  1305. (CodepageAttrstartNames[i].m_tag == tag))
  1306. {
  1307. break;
  1308. }
  1309. i++;
  1310. }
  1311. /* Duplicate the value because it may be concatenated to */
  1312. if (CodepageAttrstartNames[i].m_valueprefix)
  1313. {
  1314. *value = strdup(CodepageAttrstartNames[i].m_valueprefix);
  1315. }
  1316. else
  1317. {
  1318. *value = NULL;
  1319. }
  1320. /* Return the tag name */
  1321. return CodepageAttrstartNames[i].m_name;
  1322. }
  1323. static void CodepageAttrvalueName(WBXML_CODEPAGE page, WBXML_TAG tag, char** value)
  1324. {
  1325. int i = 0;
  1326. /* Check Parameters */
  1327. if (!value)
  1328. {
  1329. ParseError(ERR_INTERNAL_BAD_PARAM);
  1330. }
  1331. /* Search the tag list for a match */
  1332. while (CodepageAttrvalueNames[i].m_name)
  1333. {
  1334. if ((CodepageAttrvalueNames[i].m_dtd_id == dtd_id) &&
  1335. (CodepageAttrvalueNames[i].m_page == page) &&
  1336. (CodepageAttrvalueNames[i].m_tag == tag))
  1337. {
  1338. break;
  1339. }
  1340. i++;
  1341. }
  1342. /* concatenate the value */
  1343. if (CodepageAttrvalueNames[i].m_name)
  1344. {
  1345. if (*value)
  1346. {
  1347. *value = realloc(*value, strlen(*value) + strlen(CodepageAttrvalueNames[i].m_name) + 1);
  1348. strcat(*value, CodepageAttrvalueNames[i].m_name);
  1349. }
  1350. else
  1351. {
  1352. *value = strdup(CodepageAttrvalueNames[i].m_name);
  1353. }
  1354. }
  1355. }
  1356. static const char* GetStringTableString(P_WBXML_NODE node, long index)
  1357. {
  1358. /* Find the string table node */
  1359. P_WBXML_NODE pStringsNode = node;
  1360. while (pStringsNode->m_parent)
  1361. {
  1362. pStringsNode = pStringsNode->m_parent;
  1363. }
  1364. while (pStringsNode->m_next)
  1365. {
  1366. pStringsNode = pStringsNode->m_next;
  1367. }
  1368. while (pStringsNode->m_prev && pStringsNode->m_type != NODE_STRING_TABLE)
  1369. {
  1370. pStringsNode = pStringsNode->m_prev;
  1371. }
  1372. if (pStringsNode->m_type != NODE_STRING_TABLE)
  1373. {
  1374. return "!!NO STRING TABLE!!";
  1375. }
  1376. /* Find the indexed string */
  1377. if ((index >= 0) && (index < mb_u_int32_to_long(&((P_WBXML_STRING_TABLE)pStringsNode->m_data)->m_length)))
  1378. {
  1379. return (const char*) &(((P_WBXML_STRING_TABLE)pStringsNode->m_data)->m_strings[index]);
  1380. }
  1381. else
  1382. {
  1383. return "!!STRING TABLE INDEX TOO LARGE!!";
  1384. }
  1385. }
  1386. static void DumpNode(P_WBXML_NODE node, int indent, BOOL *inattrs, BOOL hascontent, char** value)
  1387. {
  1388. P_WBXML_NODE curnode = node->m_child;
  1389. WBXML_TAG nodetype = 0;
  1390. long dtdnum = 0;
  1391. BOOL bAttributesFollow = FALSE;
  1392. BOOL bHasContent = FALSE;
  1393. int i;
  1394. if (!(*inattrs))
  1395. {
  1396. for (i=0; i<indent; i++)
  1397. {
  1398. printf(" ");
  1399. }
  1400. }
  1401. else
  1402. {
  1403. if ((node->m_type != NODE_ATTRVALUE) && (*value))
  1404. {
  1405. printf("="");
  1406. OutputEncodedString((unsigned char*) *value);
  1407. printf(""");
  1408. free(*value);
  1409. *value = NULL;
  1410. }
  1411. }
  1412. switch (node->m_type)
  1413. {
  1414. case NODE_DTD_TYPE:
  1415. printf("<?xml version="1.0"?>n<!DOCTYPE wml PUBLIC ");
  1416. dtdnum = mb_u_int32_to_long( &((DTD_NODE_DATA*)node->m_data)->m_dtdnum );
  1417. if ( dtdnum == 0)
  1418. {
  1419. printf(""%s">nn", GetStringTableString(node, mb_u_int32_to_long(&((DTD_NODE_DATA*)node->m_data)->m_index)) );
  1420. }
  1421. else
  1422. {
  1423. printf(""%s">nn", DTDTypeName(dtdnum) );
  1424. }
  1425. break;
  1426. case NODE_CODEPAGE_TAG:
  1427. nodetype = *((P_WBXML_TAG)node->m_data);
  1428. if ((nodetype & CODEPAGE_TAG_MASK) == nodetype)
  1429. {
  1430. printf("<%s/>n", CodepageTagName(node->m_page, nodetype));
  1431. }
  1432. else
  1433. {
  1434. if ((nodetype & CODEPAGE_TAG_HAS_CONTENT) == CODEPAGE_TAG_HAS_CONTENT)
  1435. {
  1436. bHasContent = TRUE;
  1437. }
  1438. if ((nodetype & CODEPAGE_TAG_HAS_ATTRS) == CODEPAGE_TAG_HAS_ATTRS)
  1439. {
  1440. printf("<%s", CodepageTagName(node->m_page, nodetype));
  1441. bAttributesFollow = TRUE;
  1442. }
  1443. else
  1444. {
  1445. printf("<%s>n", CodepageTagName(node->m_page, nodetype));
  1446. }
  1447. }
  1448. break;
  1449. case NODE_CODEPAGE_LITERAL_TAG:
  1450. printf("<%s>n", GetStringTableString(node, mb_u_int32_to_long(((P_WBXML_MB_U_INT32)node->m_data))) );
  1451. break;
  1452. case NODE_ATTRSTART:
  1453. printf(" %s", CodepageAttrstartName(node->m_page, *((P_WBXML_TAG)node->m_data), value) );
  1454. break;
  1455. case NODE_ATTRSTART_LITERAL:
  1456. printf(" %s", GetStringTableString(node, mb_u_int32_to_long(((P_WBXML_MB_U_INT32)node->m_data))) );
  1457. break;
  1458. case NODE_ATTRVALUE:
  1459. CodepageAttrvalueName(node->m_page, *((P_WBXML_TAG)node->m_data), value);
  1460. break;
  1461. case NODE_ATTREND:
  1462. if (!hascontent)
  1463. {
  1464. printf("/");
  1465. }
  1466. printf(">n");
  1467. *inattrs = FALSE;
  1468. break;
  1469. case NODE_STRING:
  1470. if (*inattrs)
  1471. {
  1472. /* concatenate the value */
  1473. if (*value)
  1474. {
  1475. if (node->m_data)
  1476. {
  1477. *value = realloc(*value, strlen(*value) + strlen((char*) node->m_data) + 1);
  1478. strcat(*value, (char*) node->m_data);
  1479. }
  1480. }
  1481. else
  1482. {
  1483. if (node->m_data)
  1484. {
  1485. *value = strdup((char*) node->m_data);
  1486. }
  1487. }
  1488. }
  1489. else
  1490. {
  1491. OutputEncodedString((unsigned char*) node->m_data);
  1492. printf("n");
  1493. }
  1494. break;
  1495. case NODE_VARIABLE_STRING:
  1496. // TODO: output variable string
  1497. break;
  1498. case NODE_VARIABLE_INDEX:
  1499. // TODO: output variable string
  1500. break;
  1501. default:
  1502. break;
  1503. }
  1504. indent += INDENT_SIZE;
  1505. if (curnode)
  1506. {
  1507. while (curnode->m_next) curnode = curnode->m_next;
  1508. while (curnode)
  1509. {
  1510. DumpNode(curnode, indent, &bAttributesFollow, bHasContent, value);
  1511. curnode = curnode->m_prev;
  1512. }
  1513. }
  1514. indent -= INDENT_SIZE;
  1515. /* Output the element end if we have one */
  1516. if ((nodetype & CODEPAGE_TAG_HAS_CONTENT) == CODEPAGE_TAG_HAS_CONTENT)
  1517. {
  1518. for (i=0; i<indent; i++)
  1519. {
  1520. printf(" ");
  1521. }
  1522. switch (node->m_type)
  1523. {
  1524. case NODE_CODEPAGE_TAG:
  1525. printf("</%s>n", CodepageTagName(node->m_page, *((P_WBXML_TAG)node->m_data)) );
  1526. break;
  1527. case NODE_CODEPAGE_LITERAL_TAG:
  1528. printf("</%s>n", GetStringTableString(node, mb_u_int32_to_long(((P_WBXML_MB_U_INT32)node->m_data))) );
  1529. break;
  1530. default:
  1531. break;
  1532. }
  1533. }
  1534. }
  1535. static void DumpNodes(P_WBXML_INFO buffer)
  1536. {
  1537. P_WBXML_NODE curnode = buffer->m_tree;
  1538. BOOL bAttrsFollow = FALSE;
  1539. char* value = NULL;
  1540. if (curnode)
  1541. {
  1542. while (curnode->m_next) curnode = curnode->m_next;
  1543. while (curnode)
  1544. {
  1545. DumpNode(curnode, 0, &bAttrsFollow, FALSE, &value);
  1546. curnode = curnode->m_prev;
  1547. }
  1548. }
  1549. }
  1550. int main(int argc, char** argv)
  1551. {
  1552. WBXML_INFO buffer;
  1553. FILE* file;
  1554. if (argc < 2)
  1555. {
  1556. file = stdin;
  1557. }
  1558. else
  1559. {
  1560.         file = fopen(argv[1], "r");
  1561. if (!file)
  1562. {
  1563. ParseError(ERR_FILE_NOT_FOUND);
  1564. }
  1565. }
  1566.     Init(&buffer);
  1567. ReadBinary(&buffer, file);
  1568. Read_start(&buffer);
  1569. DumpNodes(&buffer);
  1570. Free(&buffer);
  1571. return 0;
  1572. }