Back to index

courier  0.68.2
filter.c
Go to the documentation of this file.
00001 #include "config.h"
00002 
00003 /*
00004 ** Copyright 1998 - 2011 Double Precision, Inc.  See COPYING for
00005 ** distribution information.
00006 */
00007 
00008 
00009 /*
00010 */
00011 #include      "filter.h"
00012 #include      "buf.h"
00013 #include      "sqwebmail.h"
00014 #include      <string.h>
00015 
00016 static int converted_text(const char *buf,
00017                        size_t size,
00018                        void *arg)
00019 {
00020        struct filter_info *info=(struct filter_info *)arg;
00021 
00022        (*info->handler_func)(buf, size, info->func_arg);
00023        return 0;
00024 }
00025 
00026 void   filter_start(struct filter_info *info,
00027                    const char *charset,
00028                    void (*handler)(const char *, size_t, void *),
00029                    void *arg)
00030 {
00031        info->conversion_error=0;
00032        info->handle=libmail_u_convert_init(libmail_u_ucs4_native,
00033                                        charset,
00034                                        converted_text, info);
00035 
00036        if (info->handle == NULL)
00037               info->conversion_error=1;
00038 
00039        info->handler_func=handler;
00040        info->func_arg=arg;
00041        info->u_w=0;
00042 
00043        info->linesize=MYLINESIZE + 10;
00044        info->prevchar='\n';
00045 }
00046 
00047 void   filter(struct filter_info *info,
00048               const unicode_char *ptr, size_t cnt)
00049 {
00050        size_t i, prev;
00051 
00052        if (!info->handle)
00053               return;
00054 
00055        i=prev=0;
00056 
00057        while (1)
00058        {
00059               const char *p=0;
00060               unicode_char prevchar=info->prevchar;
00061 
00062               if (i < cnt)
00063               {
00064                      info->prevchar=ptr[i];
00065 
00066                      if (ptr[i] == '\n')
00067                      {
00068                             info->u_w=0;
00069                      }
00070                      else
00071                      {
00072                             /* Force-break excessively long lines */
00073 
00074                             size_t uc_w=unicode_wcwidth(ptr[i]);
00075 
00076                             if (uc_w + info->u_w > info->linesize &&
00077                                 unicode_grapheme_break(prevchar, ptr[i]))
00078                             {
00079                                    unicode_char nl='\n';
00080 
00081                                    if (prev < i)
00082                                           libmail_u_convert_uc
00083                                                  (info->handle,
00084                                                   ptr+prev, i-prev);
00085                                    prev=i;
00086 
00087                                    libmail_u_convert_uc(info->handle,
00088                                                       &nl, 1);
00089                                    info->u_w=0;
00090                             }
00091 
00092                             info->u_w += uc_w;
00093                      }
00094 
00095                      switch (ptr[i]) {
00096                      case '<':
00097                             p="&lt;";
00098                             break;
00099                      case '>':
00100                             p="&gt;";
00101                             break;
00102                      case '&':
00103                             p="&amp;";
00104                             break;
00105                      case '"':
00106                             p="&quot;";
00107                             break;
00108                      default:
00109                             ++i;
00110                             continue;
00111                      }
00112               }
00113 
00114               if (prev < i)
00115                      libmail_u_convert_uc(info->handle, ptr+prev, i-prev);
00116               prev=++i;
00117 
00118               if (!p)
00119                      break;
00120 
00121               while (*p)
00122               {
00123                      unicode_char uc= *p++;
00124 
00125                      libmail_u_convert_uc(info->handle, &uc, 1);
00126               }
00127        }
00128 }
00129 
00130 void   filter_passthru(struct filter_info *info,
00131                      const unicode_char *ptr, size_t cnt)
00132 {
00133        libmail_u_convert_uc(info->handle, ptr, cnt);
00134 }
00135 
00136 void   filter_end(struct filter_info *info)
00137 {
00138        if (info->handle)
00139        {
00140               libmail_u_convert_deinit(info->handle,
00141                                     &info->conversion_error);
00142               info->handle=NULL;
00143        }
00144 }