Annotation of embedaddon/php/ext/mbstring/libmbfl/filters/mbfilter_qprint.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * "streamable kanji code filter and converter"
                      3:  * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
                      4:  *
                      5:  * LICENSE NOTICES
                      6:  *
                      7:  * This file is part of "streamable kanji code filter and converter",
                      8:  * which is distributed under the terms of GNU Lesser General Public 
                      9:  * License (version 2) as published by the Free Software Foundation.
                     10:  *
                     11:  * This software is distributed in the hope that it will be useful,
                     12:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14:  * GNU Lesser General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU Lesser General Public
                     17:  * License along with "streamable kanji code filter and converter";
                     18:  * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
                     19:  * Suite 330, Boston, MA  02111-1307  USA
                     20:  *
                     21:  * The author of this file:
                     22:  *
                     23:  */
                     24: /*
                     25:  * The source code included in this files was separated from mbfilter.c
                     26:  * by moriyoshi koizumi <moriyoshi@php.net> on 4 dec 2002.
                     27:  * 
                     28:  */
                     29: 
                     30: #ifdef HAVE_CONFIG_H
                     31: #include "config.h"
                     32: #endif
                     33: 
                     34: #include "mbfilter.h"
                     35: #include "mbfilter_qprint.h"
                     36: #include "unicode_prop.h"
                     37: 
                     38: static const char *mbfl_encoding_qprint_aliases[] = {"qprint", NULL};
                     39: 
                     40: const mbfl_encoding mbfl_encoding_qprint = {
                     41:        mbfl_no_encoding_qprint,
                     42:        "Quoted-Printable",
                     43:        "Quoted-Printable",
                     44:        (const char *(*)[])&mbfl_encoding_qprint_aliases,
                     45:        NULL,
                     46:        MBFL_ENCTYPE_SBCS
                     47: };
                     48: 
                     49: const struct mbfl_convert_vtbl vtbl_8bit_qprint = {
                     50:        mbfl_no_encoding_8bit,
                     51:        mbfl_no_encoding_qprint,
                     52:        mbfl_filt_conv_common_ctor,
                     53:        mbfl_filt_conv_common_dtor,
                     54:        mbfl_filt_conv_qprintenc,
                     55:        mbfl_filt_conv_qprintenc_flush };
                     56: 
                     57: const struct mbfl_convert_vtbl vtbl_qprint_8bit = {
                     58:        mbfl_no_encoding_qprint,
                     59:        mbfl_no_encoding_8bit,
                     60:        mbfl_filt_conv_common_ctor,
                     61:        mbfl_filt_conv_common_dtor,
                     62:        mbfl_filt_conv_qprintdec,
                     63:        mbfl_filt_conv_qprintdec_flush };
                     64: 
                     65: 
                     66: #define CK(statement)  do { if ((statement) < 0) return (-1); } while (0)
                     67: 
                     68: /*
                     69:  * any => Quoted-Printable
                     70:  */
                     71: 
                     72: int mbfl_filt_conv_qprintenc(int c, mbfl_convert_filter *filter)
                     73: {
                     74:        int s, n;
                     75: 
                     76:        switch (filter->status & 0xff) {
                     77:        case 0:
                     78:                filter->cache = c;
                     79:                filter->status++;
                     80:                break;
                     81:        default:
                     82:                s = filter->cache;
                     83:                filter->cache = c;
                     84:                n = (filter->status & 0xff00) >> 8;
                     85: 
                     86:                if (s == 0) {           /* null */
                     87:                        CK((*filter->output_function)(s, filter->data));
                     88:                        filter->status &= ~0xff00;
                     89:                        break;
                     90:                }
                     91: 
                     92:                if ((filter->status & MBFL_QPRINT_STS_MIME_HEADER) == 0) {
                     93:                        if (s == 0x0a || (s == 0x0d && c != 0x0a)) {    /* line feed */
                     94:                                CK((*filter->output_function)(0x0d, filter->data));             /* CR */
                     95:                                CK((*filter->output_function)(0x0a, filter->data));             /* LF */
                     96:                                filter->status &= ~0xff00;
                     97:                                break;
                     98:                        } else if (s == 0x0d) {
                     99:                                break;
                    100:                        }
                    101:                }
                    102: 
                    103:                if ((filter->status & MBFL_QPRINT_STS_MIME_HEADER) == 0  && n >= 72) {  /* soft line feed */
                    104:                        CK((*filter->output_function)(0x3d, filter->data));             /* '=' */
                    105:                        CK((*filter->output_function)(0x0d, filter->data));             /* CR */
                    106:                        CK((*filter->output_function)(0x0a, filter->data));             /* LF */
                    107:                        filter->status &= ~0xff00;
                    108:                }
                    109: 
                    110:                if (s <= 0 || s >= 0x80 || s == 0x3d            /* not ASCII or '=' */
                    111:                   || ((filter->status & MBFL_QPRINT_STS_MIME_HEADER) != 0 && 
                    112:                       (mbfl_charprop_table[s] & MBFL_CHP_MMHQENC) != 0)) {
                    113:                        /* hex-octet */
                    114:                        CK((*filter->output_function)(0x3d, filter->data));             /* '=' */
                    115:                        n = (s >> 4) & 0xf;
                    116:                        if (n < 10) {
                    117:                                n += 48;                /* '0' */
                    118:                        } else {
                    119:                                n += 55;                /* 'A' - 10 */
                    120:                        }
                    121:                        CK((*filter->output_function)(n, filter->data));
                    122:                        n = s & 0xf;
                    123:                        if (n < 10) {
                    124:                                n += 48;
                    125:                        } else {
                    126:                                n += 55;
                    127:                        }
                    128:                        CK((*filter->output_function)(n, filter->data));
                    129:                        if ((filter->status & MBFL_QPRINT_STS_MIME_HEADER) == 0) {
                    130:                                filter->status += 0x300;
                    131:                        }
                    132:                } else {
                    133:                        CK((*filter->output_function)(s, filter->data));
                    134:                        if ((filter->status & MBFL_QPRINT_STS_MIME_HEADER) == 0) {
                    135:                                filter->status += 0x100;
                    136:                        }
                    137:                }
                    138:                break;
                    139:        }
                    140: 
                    141:        return c;
                    142: }
                    143: 
                    144: int mbfl_filt_conv_qprintenc_flush(mbfl_convert_filter *filter)
                    145: {
                    146:        /* flush filter cache */
                    147:        (*filter->filter_function)('\0', filter);
                    148:        filter->status &= ~0xffff;
                    149:        filter->cache = 0;
                    150:        return 0;
                    151: }
                    152: 
                    153: /*
                    154:  * Quoted-Printable => any
                    155:  */
                    156: int mbfl_filt_conv_qprintdec(int c, mbfl_convert_filter *filter)
                    157: {
                    158:        int n, m;
                    159: 
                    160:        static int hex2code_map[] = {
                    161:                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                    162:                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                    163:                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                    164:                 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
                    165:                -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                    166:                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                    167:                -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                    168:                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                    169:                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                    170:                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                    171:                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                    172:                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                    173:                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                    174:                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                    175:                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
                    176:                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
                    177:        };
                    178: 
                    179:        switch (filter->status) {
                    180:        case 1:
                    181:                if (hex2code_map[c & 0xff] >= 0) {
                    182:                        filter->cache = c;
                    183:                        filter->status = 2;
                    184:                } else if (c == 0x0d) { /* soft line feed */
                    185:                        filter->status = 3;
                    186:                } else if (c == 0x0a) { /* soft line feed */
                    187:                        filter->status = 0;
                    188:                } else {
                    189:                        CK((*filter->output_function)(0x3d, filter->data));             /* '=' */
                    190:                        CK((*filter->output_function)(c, filter->data));
                    191:                        filter->status = 0;
                    192:                }
                    193:                break;
                    194:        case 2:
                    195:                m = hex2code_map[c & 0xff];
                    196:                if (m < 0) {
                    197:                        CK((*filter->output_function)(0x3d, filter->data));             /* '=' */
                    198:                        CK((*filter->output_function)(filter->cache, filter->data));
                    199:                        n = c;
                    200:                } else {
                    201:                        n = hex2code_map[filter->cache] << 4 | m;
                    202:                }
                    203:                CK((*filter->output_function)(n, filter->data));
                    204:                filter->status = 0;
                    205:                break;
                    206:        case 3:
                    207:                if (c != 0x0a) {                /* LF */
                    208:                        CK((*filter->output_function)(c, filter->data));
                    209:                }
                    210:                filter->status = 0;
                    211:                break;
                    212:        default:
                    213:                if (c == 0x3d) {                /* '=' */
                    214:                        filter->status = 1;
                    215:                } else {
                    216:                        CK((*filter->output_function)(c, filter->data));
                    217:                }
                    218:                break;
                    219:        }
                    220: 
                    221:        return c;
                    222: }
                    223: 
                    224: int mbfl_filt_conv_qprintdec_flush(mbfl_convert_filter *filter)
                    225: {
                    226:        int status, cache;
                    227: 
                    228:        status = filter->status;
                    229:        cache = filter->cache;
                    230:        filter->status = 0;
                    231:        filter->cache = 0;
                    232:        /* flush fragments */
                    233:        if (status == 1) {
                    234:                CK((*filter->output_function)(0x3d, filter->data));             /* '=' */
                    235:        } else if (status == 2) {
                    236:                CK((*filter->output_function)(0x3d, filter->data));             /* '=' */
                    237:                CK((*filter->output_function)(cache, filter->data));
                    238:        }
                    239: 
                    240:        return 0;
                    241: }
                    242: 
                    243: 
                    244: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>