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

手机WAP编程

开发平台:

WINDOWS

  1. /*
  2.  * html.c - routines for manipulating HTML.
  3.  *
  4.  * Lars Wirzenius
  5.  */
  6. #include <ctype.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include "html.h"
  10. #include "gwlib/gwlib.h"
  11. #define SMS_MAX 161
  12. /* Is there a comment beginning at offset `pos'? */
  13. static int html_comment_begins(Octstr *html, long pos)
  14. {
  15.     char buf[10];
  16.     octstr_get_many_chars(buf, html, pos, 4);
  17.     buf[5] = '';
  18.     return strcmp(buf, "<!--") == 0;
  19. }
  20. /* Skip a comment in HTML. */
  21. static void skip_html_comment(Octstr *html, long *pos)
  22. {
  23.     long i;
  24.     *pos += 4;  /* Skip "<!--" at beginning of comment. */
  25.     i = octstr_search(html, octstr_imm("-->"), *pos);
  26.     if (i == -1)
  27.         *pos = octstr_len(html);
  28.     else
  29.         *pos = i;
  30. }
  31. /* Skip a beginning or ending tag in HTML, including any attributes. */
  32. static void skip_html_tag(Octstr *html, long *pos)
  33. {
  34.     long i, len;
  35.     int c;
  36.     /* Skip leading '<'. */
  37.     ++(*pos);
  38.     /* Skip name of tag and attributes with values. */
  39.     len = octstr_len(html);
  40.     while (*pos < len && (c = octstr_get_char(html, *pos)) != '>') {
  41.         if (c == '"' || c == ''') {
  42.             i = octstr_search_char(html, c, *pos + 1);
  43.             if (i == -1)
  44.                 *pos = len;
  45.             else
  46.                 *pos = i + 1;
  47.         } else
  48.             ++(*pos);
  49.     }
  50.     /* Skip trailing '>' if it is there. */
  51.     if (octstr_get_char(html, *pos) == '>')
  52.         ++(*pos);
  53. }
  54. /* Convert an HTML entity into a single character and advance `*html' past
  55.    the entity. */
  56. static void convert_html_entity(Octstr *sms, Octstr *html, long *pos)
  57. {
  58.     static struct {
  59.         char *entity;
  60.         int latin1;
  61.     }
  62.     tab[] = {
  63.         { "&amp;", '&' },
  64.         { "&lt;", '<' },
  65.         { "&gt;", '>' },
  66.         /* The following is copied from
  67.          http://www.hut.fi/~jkorpela/HTML3.2/latin1.html
  68.            by Jukka Korpela. Hand and script edited to form this
  69.            table. */
  70.         { "&nbsp;", ' ' },
  71.         { "&iexcl;", 161 },
  72.         { "&cent;", 162 },
  73.         { "&pound;", 163 },
  74.         { "&curren;", 164 },
  75.         { "&yen;", 165 },
  76.         { "&brvbar;", 166 },
  77.         { "&sect;", 167 },
  78.         { "&uml;", 168 },
  79.         { "&copy;", 169 },
  80.         { "&ordf;", 170 },
  81.         { "&laquo;", 171 },
  82.         { "&not;", 172 },
  83.         { "&shy;", 173 },
  84.         { "&reg;", 174 },
  85.         { "&macr;", 175 },
  86.         { "&deg;", 176 },
  87.         { "&plusmn;", 177 },
  88.         { "&sup2;", 178 },
  89.         { "&sup3;", 179 },
  90.         { "&acute;", 180 },
  91.         { "&micro;", 181 },
  92.         { "&para;", 182 },
  93.         { "&middot;", 183 },
  94.         { "&cedil;", 184 },
  95.         { "&sup1;", 185 },
  96.         { "&ordm;", 186 },
  97.         { "&raquo;", 187 },
  98.         { "&frac14;", 188 },
  99.         { "&frac12;", 189 },
  100.         { "&frac34;", 190 },
  101.         { "&iquest;", 191 },
  102.         { "&Agrave;", 192 },
  103.         { "&Aacute;", 193 },
  104.         { "&Acirc;", 194 },
  105.         { "&Atilde;", 195 },
  106.         { "&Auml;", 196 },
  107.         { "&Aring;", 197 },
  108.         { "&AElig;", 198 },
  109.         { "&Ccedil;", 199 },
  110.         { "&Egrave;", 200 },
  111.         { "&Eacute;", 201 },
  112.         { "&Ecirc;", 202 },
  113.         { "&Euml;", 203 },
  114.         { "&Igrave;", 204 },
  115.         { "&Iacute;", 205 },
  116.         { "&Icirc;", 206 },
  117.         { "&Iuml;", 207 },
  118.         { "&ETH;", 208 },
  119.         { "&Ntilde;", 209 },
  120.         { "&Ograve;", 210 },
  121.         { "&Oacute;", 211 },
  122.         { "&Ocirc;", 212 },
  123.         { "&Otilde;", 213 },
  124.         { "&Ouml;", 214 },
  125.         { "&times;", 215 },
  126.         { "&Oslash;", 216 },
  127.         { "&Ugrave;", 217 },
  128.         { "&Uacute;", 218 },
  129.         { "&Ucirc;", 219 },
  130.         { "&Uuml;", 220 },
  131.         { "&Yacute;", 221 },
  132.         { "&THORN;", 222 },
  133.         { "&szlig;", 223 },
  134.         { "&agrave;", 224 },
  135.         { "&aacute;", 225 },
  136.         { "&acirc;", 226 },
  137.         { "&atilde;", 227 },
  138.         { "&auml;", 228 },
  139.         { "&aring;", 229 },
  140.         { "&aelig;", 230 },
  141.         { "&ccedil;", 231 },
  142.         { "&egrave;", 232 },
  143.         { "&eacute;", 233 },
  144.         { "&ecirc;", 234 },
  145.         { "&euml;", 235 },
  146.         { "&igrave;", 236 },
  147.         { "&iacute;", 237 },
  148.         { "&icirc;", 238 },
  149.         { "&iuml;", 239 },
  150.         { "&eth;", 240 },
  151.         { "&ntilde;", 241 },
  152.         { "&ograve;", 242 },
  153.         { "&oacute;", 243 },
  154.         { "&ocirc;", 244 },
  155.         { "&otilde;", 245 },
  156.         { "&ouml;", 246 },
  157.         { "&divide;", 247 },
  158.         { "&oslash;", 248 },
  159.         { "&ugrave;", 249 },
  160.         { "&uacute;", 250 },
  161.         { "&ucirc;", 251 },
  162.         { "&uuml;", 252 },
  163.         { "&yacute;", 253 },
  164.         { "&thorn;", 254 },
  165.         { "&yuml;", 255 },
  166.     };
  167.     int num_tab = sizeof(tab) / sizeof(tab[0]);
  168.     long i, code;
  169.     size_t len;
  170.     char buf[1024];
  171.     if (octstr_get_char(html, (*pos) + 1) == '#') {
  172.         i = octstr_parse_long(&code, html, (*pos) + 2, 10);
  173.         if (i > 0) {
  174.             if (code < 256)
  175.                 octstr_append_char(sms, code);
  176.             *pos = i + 1;
  177.             if (octstr_get_char(html, *pos) == ';')
  178.                 ++(*pos);
  179.         }
  180.     } else {
  181.         for (i = 0; i < num_tab; ++i) {
  182.             len = strlen(tab[i].entity);
  183.             octstr_get_many_chars(buf, html, *pos, len);
  184.             buf[len] = '';
  185.             if (strcmp(buf, tab[i].entity) == 0) {
  186.                 *pos += len;
  187.                 octstr_append_char(sms, tab[i].latin1);
  188.                 break;
  189.             }
  190.         }
  191.         if (i == num_tab) {
  192.             ++(*pos);
  193.             octstr_append_char(sms, '&');
  194.         }
  195.     }
  196. }
  197. Octstr *html_to_sms(Octstr *html)
  198. {
  199.     long i, len;
  200.     int c;
  201.     Octstr *sms;
  202.     sms = octstr_create("");
  203.     len = octstr_len(html);
  204.     i = 0;
  205.     while (i < len) {
  206.         c = octstr_get_char(html, i);
  207.         switch (c) {
  208.         case '<':
  209.             if (html_comment_begins(html, i))
  210.                 skip_html_comment(html, &i);
  211.             else
  212.                 skip_html_tag(html, &i);
  213.             break;
  214.         case '&':
  215.             convert_html_entity(sms, html, &i);
  216.             break;
  217.         default:
  218.             octstr_append_char(sms, c);
  219.             ++i;
  220.             break;
  221.         }
  222.     }
  223.     octstr_shrink_blanks(sms);
  224.     octstr_strip_blanks(sms);
  225.     return sms;
  226. }