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 20 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 #ifdef HAVE_STDDEF_H
36 #include <stddef.h>
37 #endif
38
39 #include <string.h>
40 #include "mbfl_allocators.h"
41 #include "mbfl_string.h"
42 #include "mbfl_memory_device.h"
43
44 /*
45 * memory device output functions
46 */
47 void
mbfl_memory_device_init(mbfl_memory_device * device,size_t initsz,size_t allocsz)48 mbfl_memory_device_init(mbfl_memory_device *device, size_t initsz, size_t allocsz)
49 {
50 if (device) {
51 device->length = 0;
52 device->buffer = NULL;
53 if (initsz > 0) {
54 device->buffer = (unsigned char *)mbfl_malloc(initsz);
55 if (device->buffer != NULL) {
56 device->length = initsz;
57 }
58 }
59 device->pos = 0;
60 if (allocsz > MBFL_MEMORY_DEVICE_ALLOC_SIZE) {
61 device->allocsz = allocsz;
62 } else {
63 device->allocsz = MBFL_MEMORY_DEVICE_ALLOC_SIZE;
64 }
65 }
66 }
67
68 void
mbfl_memory_device_realloc(mbfl_memory_device * device,size_t initsz,size_t allocsz)69 mbfl_memory_device_realloc(mbfl_memory_device *device, size_t initsz, size_t allocsz)
70 {
71 unsigned char *tmp;
72
73 if (device) {
74 if (initsz > device->length) {
75 tmp = (unsigned char *)mbfl_realloc((void *)device->buffer, initsz);
76 if (tmp != NULL) {
77 device->buffer = tmp;
78 device->length = initsz;
79 }
80 }
81 if (allocsz > MBFL_MEMORY_DEVICE_ALLOC_SIZE) {
82 device->allocsz = allocsz;
83 } else {
84 device->allocsz = MBFL_MEMORY_DEVICE_ALLOC_SIZE;
85 }
86 }
87 }
88
89 void
mbfl_memory_device_clear(mbfl_memory_device * device)90 mbfl_memory_device_clear(mbfl_memory_device *device)
91 {
92 if (device) {
93 if (device->buffer) {
94 mbfl_free(device->buffer);
95 }
96 device->buffer = NULL;
97 device->length = 0;
98 device->pos = 0;
99 }
100 }
101
102 void
mbfl_memory_device_reset(mbfl_memory_device * device)103 mbfl_memory_device_reset(mbfl_memory_device *device)
104 {
105 if (device) {
106 device->pos = 0;
107 }
108 }
109
110 void
mbfl_memory_device_unput(mbfl_memory_device * device)111 mbfl_memory_device_unput(mbfl_memory_device *device)
112 {
113 if (device->pos > 0) {
114 device->pos--;
115 }
116 }
117
118 mbfl_string *
mbfl_memory_device_result(mbfl_memory_device * device,mbfl_string * result)119 mbfl_memory_device_result(mbfl_memory_device *device, mbfl_string *result)
120 {
121 if (device && result) {
122 result->len = device->pos;
123 mbfl_memory_device_output('\0', device);
124 result->val = device->buffer;
125 device->buffer = NULL;
126 device->length = 0;
127 device->pos= 0;
128 if (result->val == NULL) {
129 result->len = 0;
130 result = NULL;
131 }
132 } else {
133 result = NULL;
134 }
135
136 return result;
137 }
138
139 int
mbfl_memory_device_output(int c,void * data)140 mbfl_memory_device_output(int c, void *data)
141 {
142 mbfl_memory_device *device = (mbfl_memory_device *)data;
143
144 if (device->pos >= device->length) {
145 /* reallocate buffer */
146 size_t newlen;
147 unsigned char *tmp;
148
149 if (device->length > SIZE_MAX - device->allocsz) {
150 /* overflow */
151 return -1;
152 }
153
154 newlen = device->length + device->allocsz;
155 tmp = (unsigned char *)mbfl_realloc((void *)device->buffer, newlen);
156 if (tmp == NULL) {
157 return -1;
158 }
159 device->length = newlen;
160 device->buffer = tmp;
161 }
162
163 device->buffer[device->pos++] = (unsigned char)c;
164 return c;
165 }
166
167 int
mbfl_memory_device_output2(int c,void * data)168 mbfl_memory_device_output2(int c, void *data)
169 {
170 mbfl_memory_device *device = (mbfl_memory_device *)data;
171
172 if (2 > device->length - device->pos) {
173 /* reallocate buffer */
174 size_t newlen;
175 unsigned char *tmp;
176
177 if (device->length > SIZE_MAX - device->allocsz) {
178 /* overflow */
179 return -1;
180 }
181
182 newlen = device->length + device->allocsz;
183 tmp = (unsigned char *)mbfl_realloc((void *)device->buffer, newlen);
184 if (tmp == NULL) {
185 return -1;
186 }
187 device->length = newlen;
188 device->buffer = tmp;
189 }
190
191 device->buffer[device->pos++] = (unsigned char)((c >> 8) & 0xff);
192 device->buffer[device->pos++] = (unsigned char)(c & 0xff);
193
194 return c;
195 }
196
197 int
mbfl_memory_device_output4(int c,void * data)198 mbfl_memory_device_output4(int c, void* data)
199 {
200 mbfl_memory_device *device = (mbfl_memory_device *)data;
201
202 if (4 > device->length - device->pos) {
203 /* reallocate buffer */
204 size_t newlen;
205 unsigned char *tmp;
206
207 if (device->length > SIZE_MAX - device->allocsz) {
208 /* overflow */
209 return -1;
210 }
211
212 newlen = device->length + device->allocsz;
213 tmp = (unsigned char *)mbfl_realloc((void *)device->buffer, newlen);
214 if (tmp == NULL) {
215 return -1;
216 }
217 device->length = newlen;
218 device->buffer = tmp;
219 }
220
221 device->buffer[device->pos++] = (unsigned char)((c >> 24) & 0xff);
222 device->buffer[device->pos++] = (unsigned char)((c >> 16) & 0xff);
223 device->buffer[device->pos++] = (unsigned char)((c >> 8) & 0xff);
224 device->buffer[device->pos++] = (unsigned char)(c & 0xff);
225
226 return c;
227 }
228
229 int
mbfl_memory_device_strcat(mbfl_memory_device * device,const char * psrc)230 mbfl_memory_device_strcat(mbfl_memory_device *device, const char *psrc)
231 {
232 return mbfl_memory_device_strncat(device, psrc, strlen(psrc));
233 }
234
235 int
mbfl_memory_device_strncat(mbfl_memory_device * device,const char * psrc,size_t len)236 mbfl_memory_device_strncat(mbfl_memory_device *device, const char *psrc, size_t len)
237 {
238 unsigned char *w;
239
240 if (len > device->length - device->pos) {
241 /* reallocate buffer */
242 size_t newlen;
243 unsigned char *tmp;
244
245 if (len > SIZE_MAX - MBFL_MEMORY_DEVICE_ALLOC_SIZE
246 || device->length > SIZE_MAX - (len + MBFL_MEMORY_DEVICE_ALLOC_SIZE)) {
247 /* overflow */
248 return -1;
249 }
250
251 newlen = device->length + len + MBFL_MEMORY_DEVICE_ALLOC_SIZE;
252 tmp = (unsigned char *)mbfl_realloc((void *)device->buffer, newlen);
253 if (tmp == NULL) {
254 return -1;
255 }
256
257 device->length = newlen;
258 device->buffer = tmp;
259 }
260
261 w = &device->buffer[device->pos];
262 memcpy(w, psrc, len);
263 device->pos += len;
264
265 return 0;
266 }
267
268 int
mbfl_memory_device_devcat(mbfl_memory_device * dest,mbfl_memory_device * src)269 mbfl_memory_device_devcat(mbfl_memory_device *dest, mbfl_memory_device *src)
270 {
271 return mbfl_memory_device_strncat(dest, (const char *) src->buffer, src->pos);
272 }
273
274 void
mbfl_wchar_device_init(mbfl_wchar_device * device)275 mbfl_wchar_device_init(mbfl_wchar_device *device)
276 {
277 if (device) {
278 device->buffer = NULL;
279 device->length = 0;
280 device->pos= 0;
281 device->allocsz = MBFL_MEMORY_DEVICE_ALLOC_SIZE;
282 }
283 }
284
285 void
mbfl_wchar_device_clear(mbfl_wchar_device * device)286 mbfl_wchar_device_clear(mbfl_wchar_device *device)
287 {
288 if (device) {
289 if (device->buffer) {
290 mbfl_free(device->buffer);
291 }
292 device->buffer = NULL;
293 device->length = 0;
294 device->pos = 0;
295 }
296 }
297
298 int
mbfl_wchar_device_output(int c,void * data)299 mbfl_wchar_device_output(int c, void *data)
300 {
301 mbfl_wchar_device *device = (mbfl_wchar_device *)data;
302
303 if (device->pos >= device->length) {
304 /* reallocate buffer */
305 size_t newlen;
306 unsigned int *tmp;
307
308 if (device->length > SIZE_MAX - device->allocsz) {
309 /* overflow */
310 return -1;
311 }
312
313 newlen = device->length + device->allocsz;
314 if (newlen > SIZE_MAX / sizeof(int)) {
315 /* overflow */
316 return -1;
317 }
318
319 tmp = (unsigned int *)mbfl_realloc((void *)device->buffer, newlen*sizeof(int));
320 if (tmp == NULL) {
321 return -1;
322 }
323 device->length = newlen;
324 device->buffer = tmp;
325 }
326
327 device->buffer[device->pos++] = c;
328
329 return c;
330 }
331