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