Return to mbfilter_uuencode.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / mbstring / libmbfl / filters |
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_uuencode.h" 36: 37: const mbfl_encoding mbfl_encoding_uuencode = { 38: mbfl_no_encoding_uuencode, 39: "UUENCODE", 40: "x-uuencode", 41: NULL, 42: NULL, 43: MBFL_ENCTYPE_SBCS 44: }; 45: 46: const struct mbfl_convert_vtbl vtbl_uuencode_8bit = { 47: mbfl_no_encoding_uuencode, 48: mbfl_no_encoding_8bit, 49: mbfl_filt_conv_common_ctor, 50: mbfl_filt_conv_common_dtor, 51: mbfl_filt_conv_uudec, 52: mbfl_filt_conv_common_flush 53: }; 54: 55: #define CK(statement) do { if ((statement) < 0) return (-1); } while (0) 56: 57: /* uuencode => any */ 58: #define UUDEC(c) (char)(((c)-' ')&077) 59: static const char * uuenc_begin_text = "begin "; 60: enum { uudec_state_ground=0, uudec_state_inbegin, 61: uudec_state_until_newline, 62: uudec_state_size, uudec_state_a, uudec_state_b, uudec_state_c, uudec_state_d, 63: uudec_state_skip_newline}; 64: 65: int mbfl_filt_conv_uudec(int c, mbfl_convert_filter * filter) 66: { 67: int n; 68: 69: switch(filter->status) { 70: case uudec_state_ground: 71: /* looking for "begin 0666 filename\n" line */ 72: if (filter->cache == 0 && c == 'b') 73: { 74: filter->status = uudec_state_inbegin; 75: filter->cache = 1; /* move to 'e' */ 76: } 77: else if (c == '\n') 78: filter->cache = 0; 79: else 80: filter->cache++; 81: break; 82: case uudec_state_inbegin: 83: if (uuenc_begin_text[filter->cache++] != c) { 84: /* doesn't match pattern */ 85: filter->status = uudec_state_ground; 86: break; 87: } 88: if (filter->cache == 5) 89: { 90: /* thats good enough - wait for a newline */ 91: filter->status = uudec_state_until_newline; 92: filter->cache = 0; 93: } 94: break; 95: case uudec_state_until_newline: 96: if (c == '\n') 97: filter->status = uudec_state_size; 98: break; 99: case uudec_state_size: 100: /* get "size" byte */ 101: n = UUDEC(c); 102: filter->cache = n << 24; 103: filter->status = uudec_state_a; 104: break; 105: case uudec_state_a: 106: /* get "a" byte */ 107: n = UUDEC(c); 108: filter->cache |= (n << 16); 109: filter->status = uudec_state_b; 110: break; 111: case uudec_state_b: 112: /* get "b" byte */ 113: n = UUDEC(c); 114: filter->cache |= (n << 8); 115: filter->status = uudec_state_c; 116: break; 117: case uudec_state_c: 118: /* get "c" byte */ 119: n = UUDEC(c); 120: filter->cache |= n; 121: filter->status = uudec_state_d; 122: break; 123: case uudec_state_d: 124: /* get "d" byte */ 125: { 126: int A, B, C, D = UUDEC(c); 127: A = (filter->cache >> 16) & 0xff; 128: B = (filter->cache >> 8) & 0xff; 129: C = (filter->cache) & 0xff; 130: n = (filter->cache >> 24) & 0xff; 131: if (n-- > 0) 132: CK((*filter->output_function)( (A << 2) | (B >> 4), filter->data)); 133: if (n-- > 0) 134: CK((*filter->output_function)( (B << 4) | (C >> 2), filter->data)); 135: if (n-- > 0) 136: CK((*filter->output_function)( (C << 6) | D, filter->data)); 137: filter->cache = n << 24; 138: 139: if (n == 0) 140: filter->status = uudec_state_skip_newline; /* skip next byte (newline) */ 141: else 142: filter->status = uudec_state_a; /* go back to fetch "A" byte */ 143: } 144: break; 145: case uudec_state_skip_newline: 146: /* skip newline */ 147: filter->status = uudec_state_size; 148: } 149: return c; 150: } 151: 152: