Annotation of embedaddon/php/ext/mbstring/libmbfl/filters/mbfilter_base64.c, revision 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. 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_SBCS
! 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:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>