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 #include "mbfilter.h"
32 #include "mbfilter_7bit.h"
33 
34 static size_t mb_7bit_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state);
35 static void mb_wchar_to_7bit(uint32_t *in, size_t len, mb_convert_buf *buf, bool end);
36 
37 const struct mbfl_convert_vtbl vtbl_7bit_wchar = {
38 	mbfl_no_encoding_7bit,
39 	mbfl_no_encoding_wchar,
40 	mbfl_filt_conv_common_ctor,
41 	NULL,
42 	mbfl_filt_conv_7bit_any,
43 	mbfl_filt_conv_common_flush,
44 	NULL,
45 };
46 
47 const struct mbfl_convert_vtbl vtbl_wchar_7bit = {
48 	mbfl_no_encoding_wchar,
49 	mbfl_no_encoding_7bit,
50 	mbfl_filt_conv_common_ctor,
51 	NULL,
52 	mbfl_filt_conv_any_7bit,
53 	mbfl_filt_conv_common_flush,
54 	NULL,
55 };
56 
57 const mbfl_encoding mbfl_encoding_7bit = {
58 	mbfl_no_encoding_7bit,
59 	"7bit",
60 	"7bit",
61 	NULL,
62 	NULL,
63 	MBFL_ENCTYPE_SBCS,
64 	&vtbl_7bit_wchar,
65 	&vtbl_wchar_7bit,
66 	mb_7bit_to_wchar,
67 	mb_wchar_to_7bit,
68 	NULL,
69 	NULL,
70 };
71 
72 #define CK(statement)	do { if ((statement) < 0) return (-1); } while (0)
73 
mbfl_filt_conv_7bit_any(int c,mbfl_convert_filter * filter)74 int mbfl_filt_conv_7bit_any(int c, mbfl_convert_filter *filter)
75 {
76 	return (*filter->output_function)(c < 0x80 ? c : MBFL_BAD_INPUT, filter->data);
77 }
78 
mbfl_filt_conv_any_7bit(int c,mbfl_convert_filter * filter)79 int mbfl_filt_conv_any_7bit(int c, mbfl_convert_filter *filter)
80 {
81 	if (c >= 0 && c < 0x80) {
82 		CK((*filter->output_function)(c, filter->data));
83 	} else {
84 		CK(mbfl_filt_conv_illegal_output(c, filter));
85 	}
86 	return 0;
87 }
88 
mb_7bit_to_wchar(unsigned char ** in,size_t * in_len,uint32_t * buf,size_t bufsize,unsigned int * state)89 static size_t mb_7bit_to_wchar(unsigned char **in, size_t *in_len, uint32_t *buf, size_t bufsize, unsigned int *state)
90 {
91   unsigned char *p = *in, *e = p + *in_len;
92   uint32_t *out = buf, *limit = buf + bufsize;
93 
94   while (p < e && out < limit) {
95     unsigned char c = *p++;
96     *out++ = (c < 0x80) ? c : MBFL_BAD_INPUT;
97   }
98 
99   *in_len = e - p;
100   *in = p;
101   return out - buf;
102 }
103 
mb_wchar_to_7bit(uint32_t * in,size_t len,mb_convert_buf * buf,bool end)104 static void mb_wchar_to_7bit(uint32_t *in, size_t len, mb_convert_buf *buf, bool end)
105 {
106   unsigned char *out, *limit;
107   MB_CONVERT_BUF_LOAD(buf, out, limit);
108   MB_CONVERT_BUF_ENSURE(buf, out, limit, len);
109 
110   while (len--) {
111     uint32_t w = *in++;
112     if (w <= 0x7F) {
113       out = mb_convert_buf_add(out, w);
114     } else {
115       MB_CONVERT_ERROR(buf, out, limit, w, mb_wchar_to_7bit);
116       MB_CONVERT_BUF_ENSURE(buf, out, limit, len);
117     }
118   }
119 
120   MB_CONVERT_BUF_STORE(buf, out, limit);
121 }
122