Back to index

courier  0.68.2
encodeautodetect.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 2003-2011 Double Precision, Inc.  See COPYING for
00003 ** distribution information.
00004 */
00005 
00006 /*
00007 */
00008 #include      "encode.h"
00009 #include      <string.h>
00010 #include      <stdlib.h>
00011 #include      "../unicode/unicode.h"
00012 
00013 static const char *libmail_encode_autodetect(int use7bit,
00014                                         int (*func)(void *), void *arg,
00015                                         int *binaryflag)
00016 {
00017        int    l=0;
00018        int    longline=0;
00019        int c;
00020 
00021        size_t charcnt=0;
00022        size_t bit8cnt=0;
00023 
00024        if (binaryflag)
00025               *binaryflag=0;
00026 
00027        while ((c = (*func)(arg)) != EOF)
00028        {
00029               unsigned char ch= (unsigned char)c;
00030 
00031               ++charcnt;
00032 
00033               ++l;
00034               if (ch < 0x20 || ch >= 0x80)
00035               {
00036                      if (ch != '\t' && ch != '\r' && ch != '\n')
00037                      {
00038                             ++bit8cnt;
00039                             l += 2;
00040                      }
00041               }
00042 
00043               if (ch == 0)
00044               {
00045                      if (binaryflag)
00046                             *binaryflag=1;
00047 
00048                      return "base64";
00049               }
00050 
00051               if (ch == '\n')      l=0;
00052               else if (l > 990)
00053               {
00054                      longline=1;
00055               }
00056 
00057        }
00058 
00059        if (use7bit || longline)
00060        {
00061               if (bit8cnt > charcnt / 10)
00062                      return "base64";
00063 
00064               return "quoted-printable";
00065        }
00066 
00067        return bit8cnt ? "8bit":"7bit";
00068 }
00069 
00070 struct file_info {
00071        FILE *fp;
00072        off_t pos;
00073        off_t end;
00074 };
00075 
00076 static int read_file(void *arg)
00077 {
00078 int c;
00079 struct file_info *fi = (struct file_info *)arg;
00080        if (fi->end >= 0 && fi->pos > fi->end)
00081               return EOF;
00082        c = getc(fi->fp);
00083        fi->pos++;
00084        return c;
00085 }
00086 
00087 static int read_string(void * arg)
00088 {
00089 int c;
00090 unsigned char **strp = (unsigned char **)arg;
00091        if (**strp == 0)
00092               return EOF;
00093        c = (int)**strp;
00094        (*strp)++;
00095        return c;
00096 }
00097 
00098 const char *libmail_encode_autodetect_fp(FILE *fp, int use7bit,
00099                                     int *binaryflag)
00100 {
00101        return libmail_encode_autodetect_fpoff(fp, use7bit, 0, -1,
00102                                           binaryflag);
00103 }
00104 
00105 const char *libmail_encode_autodetect_fpoff(FILE *fp, int use7bit,
00106                                        off_t start_pos, off_t end_pos,
00107                                        int *binaryflag)
00108 {
00109 struct file_info fi;
00110 off_t orig_pos = ftell(fp);
00111 off_t pos = orig_pos;
00112 const char *rc;
00113 
00114        if (start_pos >= 0)
00115        {
00116               if (fseek(fp, start_pos, SEEK_SET) == (off_t)-1)
00117                      return NULL;
00118               else
00119                      pos = start_pos;
00120        }
00121 
00122        fi.fp = fp;
00123        fi.pos = pos;
00124        fi.end = end_pos;
00125 
00126        rc = libmail_encode_autodetect(use7bit, &read_file, &fi,
00127                                    binaryflag);
00128   
00129        if (fseek(fp, orig_pos, SEEK_SET) == (off_t)-1)
00130               return NULL;
00131        return rc;
00132 }
00133 
00134 const char *libmail_encode_autodetect_buf(const char *str, int use7bit)
00135 {
00136        return libmail_encode_autodetect(use7bit, &read_string, &str,
00137                                     NULL);
00138 }