root/ext/mbstring/libmbfl/filters/mbfilter_base64.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mbfl_filt_conv_base64enc
  2. mbfl_filt_conv_base64enc_flush
  3. mbfl_filt_conv_base64dec
  4. mbfl_filt_conv_base64dec_flush

   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. The file
  27  * mbfilter.c is included in this package .
  28  *
  29  */
  30 
  31 #ifdef HAVE_CONFIG_H
  32 #include "config.h"
  33 #endif
  34 
  35 #include "mbfilter.h"
  36 #include "mbfilter_base64.h"
  37 
  38 const mbfl_encoding mbfl_encoding_base64 = {
  39         mbfl_no_encoding_base64,
  40         "BASE64",
  41         "BASE64",
  42         NULL,
  43         NULL,
  44         MBFL_ENCTYPE_ENC_STRM | MBFL_ENCTYPE_GL_UNSAFE
  45 };
  46 
  47 const struct mbfl_convert_vtbl vtbl_8bit_b64 = {
  48         mbfl_no_encoding_8bit,
  49         mbfl_no_encoding_base64,
  50         mbfl_filt_conv_common_ctor,
  51         mbfl_filt_conv_common_dtor,
  52         mbfl_filt_conv_base64enc,
  53         mbfl_filt_conv_base64enc_flush
  54 };
  55 
  56 const struct mbfl_convert_vtbl vtbl_b64_8bit = {
  57         mbfl_no_encoding_base64,
  58         mbfl_no_encoding_8bit,
  59         mbfl_filt_conv_common_ctor,
  60         mbfl_filt_conv_common_dtor,
  61         mbfl_filt_conv_base64dec,
  62         mbfl_filt_conv_base64dec_flush
  63 };
  64 
  65 
  66 #define CK(statement)   do { if ((statement) < 0) return (-1); } while (0)
  67 
  68 /*
  69  * any => BASE64
  70  */
  71 static const unsigned char mbfl_base64_table[] = {
  72  /* 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', */
  73    0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,
  74  /* 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', */
  75    0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,
  76  /* 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', */
  77    0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,
  78  /* 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', */
  79    0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,
  80  /* '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0' */
  81    0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x2b,0x2f,0x00
  82 };
  83 
  84 int mbfl_filt_conv_base64enc(int c, mbfl_convert_filter *filter)
  85 {
  86         int n;
  87 
  88         n = (filter->status & 0xff);
  89         if (n == 0) {
  90                 filter->status++;
  91                 filter->cache = (c & 0xff) << 16;
  92         } else if (n == 1) {
  93                 filter->status++;
  94                 filter->cache |= (c & 0xff) << 8;
  95         } else {
  96                 filter->status &= ~0xff;
  97                 if ((filter->status & MBFL_BASE64_STS_MIME_HEADER) == 0) {
  98                         n = (filter->status & 0xff00) >> 8;
  99                         if (n > 72) {
 100                                 CK((*filter->output_function)(0x0d, filter->data));             /* CR */
 101                                 CK((*filter->output_function)(0x0a, filter->data));             /* LF */
 102                                 filter->status &= ~0xff00;
 103                         }
 104                         filter->status += 0x400;
 105                 }
 106                 n = filter->cache | (c & 0xff);
 107                 CK((*filter->output_function)(mbfl_base64_table[(n >> 18) & 0x3f], filter->data));
 108                 CK((*filter->output_function)(mbfl_base64_table[(n >> 12) & 0x3f], filter->data));
 109                 CK((*filter->output_function)(mbfl_base64_table[(n >> 6) & 0x3f], filter->data));
 110                 CK((*filter->output_function)(mbfl_base64_table[n & 0x3f], filter->data));
 111         }
 112 
 113         return c;
 114 }
 115 
 116 int mbfl_filt_conv_base64enc_flush(mbfl_convert_filter *filter)
 117 {
 118         int status, cache, len;
 119 
 120         status = filter->status & 0xff;
 121         cache = filter->cache;
 122         len = (filter->status & 0xff00) >> 8;
 123         filter->status &= ~0xffff;
 124         filter->cache = 0;
 125         /* flush fragments */
 126         if (status >= 1) {
 127                 if ((filter->status & MBFL_BASE64_STS_MIME_HEADER) == 0) {
 128                         if (len > 72){
 129                                 CK((*filter->output_function)(0x0d, filter->data));             /* CR */
 130                                 CK((*filter->output_function)(0x0a, filter->data));             /* LF */
 131                         }
 132                 }
 133                 CK((*filter->output_function)(mbfl_base64_table[(cache >> 18) & 0x3f], filter->data));
 134                 CK((*filter->output_function)(mbfl_base64_table[(cache >> 12) & 0x3f], filter->data));
 135                 if (status == 1) {
 136                         CK((*filter->output_function)(0x3d, filter->data));             /* '=' */
 137                         CK((*filter->output_function)(0x3d, filter->data));             /* '=' */
 138                 } else {
 139                         CK((*filter->output_function)(mbfl_base64_table[(cache >> 6) & 0x3f], filter->data));
 140                         CK((*filter->output_function)(0x3d, filter->data));             /* '=' */
 141                 }
 142         }
 143         return 0;
 144 }
 145 
 146 /*
 147  * BASE64 => any
 148  */
 149 int mbfl_filt_conv_base64dec(int c, mbfl_convert_filter *filter)
 150 {
 151         int n;
 152 
 153         if (c == 0x0d || c == 0x0a || c == 0x20 || c == 0x09 || c == 0x3d) {    /* CR or LF or SPACE or HTAB or '=' */
 154                 return c;
 155         }
 156 
 157         n = 0;
 158         if (c >= 0x41 && c <= 0x5a) {           /* A - Z */
 159                 n = c - 65;
 160         } else if (c >= 0x61 && c <= 0x7a) {    /* a - z */
 161                 n = c - 71;
 162         } else if (c >= 0x30 && c <= 0x39) {    /* 0 - 9 */
 163                 n = c + 4;
 164         } else if (c == 0x2b) {                 /* '+' */
 165                 n = 62;
 166         } else if (c == 0x2f) {                 /* '/' */
 167                 n = 63;
 168         }
 169         n &= 0x3f;
 170 
 171         switch (filter->status) {
 172         case 0:
 173                 filter->status = 1;
 174                 filter->cache = n << 18;
 175                 break;
 176         case 1:
 177                 filter->status = 2;
 178                 filter->cache |= n << 12;
 179                 break;
 180         case 2:
 181                 filter->status = 3;
 182                 filter->cache |= n << 6;
 183                 break;
 184         default:
 185                 filter->status = 0;
 186                 n |= filter->cache;
 187                 CK((*filter->output_function)((n >> 16) & 0xff, filter->data));
 188                 CK((*filter->output_function)((n >> 8) & 0xff, filter->data));
 189                 CK((*filter->output_function)(n & 0xff, filter->data));
 190                 break;
 191         }
 192 
 193         return c;
 194 }
 195 
 196 int mbfl_filt_conv_base64dec_flush(mbfl_convert_filter *filter)
 197 {
 198         int status, cache;
 199 
 200         status = filter->status;
 201         cache = filter->cache;
 202         filter->status = 0;
 203         filter->cache = 0;
 204         /* flush fragments */
 205         if (status >= 2) {
 206                 CK((*filter->output_function)((cache >> 16) & 0xff, filter->data));
 207                 if (status >= 3) {
 208                         CK((*filter->output_function)((cache >> 8) & 0xff, filter->data));
 209                 }
 210         }
 211         return 0;
 212 }
 213 
 214 

/* [<][>][^][v][top][bottom][index][help] */