Annotation of embedaddon/php/ext/mbstring/libmbfl/filters/mbfilter_uuencode.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_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:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>