filter.c
上传用户:s81996212
上传日期:2007-01-04
资源大小:722k
文件大小:3k
源码类别:

WEB邮件程序

开发平台:

C/C++

  1. /*
  2. ** Copyright 1998 - 1999 Double Precision, Inc.  See COPYING for
  3. ** distribution information.
  4. */
  5. /*
  6. ** $Id: filter.c,v 1.5 2000/05/27 04:59:27 mrsam Exp $
  7. */
  8. #include "filter.h"
  9. #include "buf.h"
  10. #include "sqwebmail.h"
  11. #include <string.h>
  12. static void (*filter_func)(const char *, size_t);
  13. /*static void filter_for_saving(const char *, size_t);*/
  14. static void filter_for_sending(const char *, size_t);
  15. static void filter_for_display(const char *, size_t);
  16. static void (*handler_func)(const char *, size_t);
  17. static struct buf disp_buf;
  18. static int linesize;
  19. void filter_start(int mode, void (*handler)(const char *, size_t))
  20. {
  21. buf_init(&disp_buf);
  22. switch (mode) {
  23. case FILTER_FOR_SAVING:
  24. filter_func=handler; /* This is a no-op, for now */
  25. break;
  26. case FILTER_FOR_SENDING:
  27. filter_func= &filter_for_sending;
  28. linesize=MYLINESIZE;
  29. break;
  30. case FILTER_FOR_DISPLAY:
  31. filter_func= &filter_for_display;
  32. linesize=EXTLINESIZE;
  33. break;
  34. case FILTER_FOR_PREVIEW:
  35. filter_func= &filter_for_display;
  36. linesize=MYLINESIZE;
  37. break;
  38. }
  39. handler_func=handler;
  40. }
  41. void filter(const char *ptr, size_t cnt)
  42. {
  43. (*filter_func)(ptr, cnt);
  44. }
  45. void filter_end(void)
  46. {
  47. (*filter_func)(0, 0);
  48. buf_free(&disp_buf);
  49. }
  50. static void wordwrap(const char *buf, size_t cnt,
  51. void (*func)(const char *, size_t))
  52. {
  53. size_t i;
  54. if (cnt == 0 || *buf == '>') /* Do not wordwrap quoted lines */
  55. {
  56. (*func)(buf, cnt);
  57. (*func)("n", 1);
  58. return;
  59. }
  60. for (i=0; i<cnt;)
  61. {
  62. size_t j;
  63. size_t spacepos, restartpos;
  64. spacepos=restartpos=cnt;
  65. for (j=i; ; j++)
  66. {
  67. if (j >= i+linesize && spacepos <= j)
  68. break;
  69. if (j >= cnt)
  70. {
  71. spacepos=restartpos=j;
  72. break;
  73. }
  74. if (buf[j] == ' ')
  75. {
  76. spacepos=j;
  77. restartpos=j+1;
  78. }
  79. }
  80. (*func)(buf+i, spacepos-i);
  81. (*func)("n", 1);
  82. i=restartpos;
  83. }
  84. }
  85. /***************************************************************************/
  86. static void dodisplay(const char *, size_t);
  87. static void filter_for_display(const char *ptr, size_t cnt)
  88. {
  89. size_t i;
  90. if (!ptr)
  91. {
  92. if (disp_buf.cnt)
  93. wordwrap(disp_buf.ptr, disp_buf.cnt, dodisplay);
  94. disp_buf.cnt=0;
  95. return;
  96. }
  97. buf_memcat(&disp_buf, ptr, cnt);
  98. for (;;)
  99. {
  100. for (i=0; i<disp_buf.cnt; i++)
  101. if (disp_buf.ptr[i] == 'n')
  102. break;
  103. if (i >= disp_buf.cnt) break;
  104. wordwrap(disp_buf.ptr, i, dodisplay);
  105. buf_trimleft(&disp_buf, i+1);
  106. }
  107. }
  108. static void dodisplay(const char *buf, size_t cnt)
  109. {
  110. size_t i,j;
  111. const char *p=0;
  112. char charbuf[6];
  113. for (i=j=0; i<cnt; i++)
  114. {
  115. switch (buf[i]) {
  116. case '<':
  117. p="&lt;"; break;
  118. case '>':
  119. p="&gt;"; break;
  120. case '&':
  121. p="&amp;"; break;
  122. case '"':
  123. p="&quot;"; break;
  124. default:
  125. if (ISCTRL(buf[i]) && buf[i] != 'n')
  126. {
  127. sprintf(charbuf, "&#%d;",
  128. (int)(unsigned char)buf[i]);
  129. p=charbuf;
  130. }
  131. else
  132. continue;
  133. }
  134. if (i > j)
  135. (*handler_func)(buf+j, i-j);
  136. (*handler_func)(p, strlen(p));
  137. j=i+1;
  138. }
  139. if (i > j)
  140. (*handler_func)(buf+j, i-j);
  141. }
  142. /***************************************************************************/
  143. static void filter_for_sending(const char *ptr, size_t cnt)
  144. {
  145. size_t i;
  146. if (!ptr)
  147. {
  148. if (disp_buf.cnt)
  149. wordwrap(disp_buf.ptr, disp_buf.cnt, handler_func);
  150. disp_buf.cnt=0;
  151. return;
  152. }
  153. buf_memcat(&disp_buf, ptr, cnt);
  154. for (;;)
  155. {
  156. for (i=0; i<disp_buf.cnt; i++)
  157. if (disp_buf.ptr[i] == 'n')
  158. break;
  159. if (i >= disp_buf.cnt) break;
  160. wordwrap(disp_buf.ptr, i, handler_func);
  161. buf_trimleft(&disp_buf, i+1);
  162. }
  163. }