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 #include <stddef.h>
32 #include <string.h>
33
34 #include "zend.h"
35 #include "mbfl_memory_device.h"
36
37 /*
38 * memory device output functions
39 */
40 void
mbfl_memory_device_init(mbfl_memory_device * device,size_t initsz,size_t allocsz)41 mbfl_memory_device_init(mbfl_memory_device *device, size_t initsz, size_t allocsz)
42 {
43 if (device) {
44 device->length = 0;
45 device->buffer = NULL;
46 if (initsz > 0) {
47 device->buffer = emalloc(initsz);
48 device->length = initsz;
49 }
50 device->pos = 0;
51 if (allocsz > MBFL_MEMORY_DEVICE_ALLOC_SIZE) {
52 device->allocsz = allocsz;
53 } else {
54 device->allocsz = MBFL_MEMORY_DEVICE_ALLOC_SIZE;
55 }
56 }
57 }
58
59 void
mbfl_memory_device_realloc(mbfl_memory_device * device,size_t initsz,size_t allocsz)60 mbfl_memory_device_realloc(mbfl_memory_device *device, size_t initsz, size_t allocsz)
61 {
62 if (device) {
63 if (initsz > device->length) {
64 device->buffer = erealloc(device->buffer, initsz);
65 device->length = initsz;
66 }
67 if (allocsz > MBFL_MEMORY_DEVICE_ALLOC_SIZE) {
68 device->allocsz = allocsz;
69 } else {
70 device->allocsz = MBFL_MEMORY_DEVICE_ALLOC_SIZE;
71 }
72 }
73 }
74
75 void
mbfl_memory_device_clear(mbfl_memory_device * device)76 mbfl_memory_device_clear(mbfl_memory_device *device)
77 {
78 if (device) {
79 if (device->buffer) {
80 efree(device->buffer);
81 }
82 device->buffer = NULL;
83 device->length = 0;
84 device->pos = 0;
85 }
86 }
87
88 void
mbfl_memory_device_reset(mbfl_memory_device * device)89 mbfl_memory_device_reset(mbfl_memory_device *device)
90 {
91 if (device) {
92 device->pos = 0;
93 }
94 }
95
96 void
mbfl_memory_device_unput(mbfl_memory_device * device)97 mbfl_memory_device_unput(mbfl_memory_device *device)
98 {
99 if (device->pos > 0) {
100 device->pos--;
101 }
102 }
103
104 mbfl_string *
mbfl_memory_device_result(mbfl_memory_device * device,mbfl_string * result)105 mbfl_memory_device_result(mbfl_memory_device *device, mbfl_string *result)
106 {
107 if (device && result) {
108 result->len = device->pos;
109 mbfl_memory_device_output('\0', device);
110 result->val = device->buffer;
111 device->buffer = NULL;
112 device->length = 0;
113 device->pos= 0;
114 if (result->val == NULL) {
115 result->len = 0;
116 result = NULL;
117 }
118 } else {
119 result = NULL;
120 }
121
122 return result;
123 }
124
125 int
mbfl_memory_device_output(int c,void * data)126 mbfl_memory_device_output(int c, void *data)
127 {
128 mbfl_memory_device *device = (mbfl_memory_device *)data;
129
130 if (device->pos >= device->length) {
131 /* reallocate buffer */
132 size_t newlen;
133
134 if (device->length > SIZE_MAX - device->allocsz) {
135 /* overflow */
136 return -1;
137 }
138
139 newlen = device->length + device->allocsz;
140 device->buffer = erealloc(device->buffer, newlen);
141 device->length = newlen;
142 }
143
144 device->buffer[device->pos++] = (unsigned char)c;
145 return c;
146 }
147
148 int
mbfl_memory_device_strcat(mbfl_memory_device * device,const char * psrc)149 mbfl_memory_device_strcat(mbfl_memory_device *device, const char *psrc)
150 {
151 return mbfl_memory_device_strncat(device, psrc, strlen(psrc));
152 }
153
154 int
mbfl_memory_device_strncat(mbfl_memory_device * device,const char * psrc,size_t len)155 mbfl_memory_device_strncat(mbfl_memory_device *device, const char *psrc, size_t len)
156 {
157 unsigned char *w;
158
159 if (len > device->length - device->pos) {
160 /* reallocate buffer */
161 size_t newlen;
162
163 if (len > SIZE_MAX - MBFL_MEMORY_DEVICE_ALLOC_SIZE
164 || device->length > SIZE_MAX - (len + MBFL_MEMORY_DEVICE_ALLOC_SIZE)) {
165 /* overflow */
166 return -1;
167 }
168
169 newlen = device->length + len + MBFL_MEMORY_DEVICE_ALLOC_SIZE;
170 device->buffer = erealloc(device->buffer, newlen);
171 device->length = newlen;
172 }
173
174 w = &device->buffer[device->pos];
175 memcpy(w, psrc, len);
176 device->pos += len;
177
178 return 0;
179 }
180
181 int
mbfl_memory_device_devcat(mbfl_memory_device * dest,mbfl_memory_device * src)182 mbfl_memory_device_devcat(mbfl_memory_device *dest, mbfl_memory_device *src)
183 {
184 return mbfl_memory_device_strncat(dest, (const char *) src->buffer, src->pos);
185 }
186
187 void
mbfl_wchar_device_init(mbfl_wchar_device * device)188 mbfl_wchar_device_init(mbfl_wchar_device *device)
189 {
190 if (device) {
191 device->buffer = NULL;
192 device->length = 0;
193 device->pos= 0;
194 device->allocsz = MBFL_MEMORY_DEVICE_ALLOC_SIZE;
195 }
196 }
197
198 void
mbfl_wchar_device_clear(mbfl_wchar_device * device)199 mbfl_wchar_device_clear(mbfl_wchar_device *device)
200 {
201 if (device) {
202 if (device->buffer) {
203 efree(device->buffer);
204 }
205 device->buffer = NULL;
206 device->length = 0;
207 device->pos = 0;
208 }
209 }
210
211 int
mbfl_wchar_device_output(int c,void * data)212 mbfl_wchar_device_output(int c, void *data)
213 {
214 mbfl_wchar_device *device = (mbfl_wchar_device *)data;
215
216 if (device->pos >= device->length) {
217 /* reallocate buffer */
218 size_t newlen;
219
220 if (device->length > SIZE_MAX - device->allocsz) {
221 /* overflow */
222 return -1;
223 }
224
225 newlen = device->length + device->allocsz;
226 if (newlen > SIZE_MAX / sizeof(int)) {
227 /* overflow */
228 return -1;
229 }
230
231 device->buffer = erealloc(device->buffer, newlen*sizeof(int));
232 device->length = newlen;
233 }
234
235 device->buffer[device->pos++] = c;
236
237 return c;
238 }
239