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 */
mbfl_memory_device_init(mbfl_memory_device * device,size_t initsz,size_t allocsz)40 void mbfl_memory_device_init(mbfl_memory_device *device, size_t initsz, size_t allocsz)
41 {
42 device->buffer = (initsz > 0) ? emalloc(initsz) : NULL;
43 device->length = initsz;
44 device->pos = 0;
45 device->allocsz = MAX(allocsz, MBFL_MEMORY_DEVICE_ALLOC_SIZE);
46 }
47
mbfl_memory_device_realloc(mbfl_memory_device * device,size_t initsz,size_t allocsz)48 void mbfl_memory_device_realloc(mbfl_memory_device *device, size_t initsz, size_t allocsz)
49 {
50 if (initsz > device->length) {
51 device->buffer = erealloc(device->buffer, initsz);
52 device->length = initsz;
53 }
54 device->allocsz = MAX(allocsz, MBFL_MEMORY_DEVICE_ALLOC_SIZE);
55 }
56
mbfl_memory_device_clear(mbfl_memory_device * device)57 void mbfl_memory_device_clear(mbfl_memory_device *device)
58 {
59 if (device->buffer) {
60 efree(device->buffer);
61 }
62 device->buffer = NULL;
63 device->length = device->pos = 0;
64 }
65
mbfl_memory_device_reset(mbfl_memory_device * device)66 void mbfl_memory_device_reset(mbfl_memory_device *device)
67 {
68 device->pos = 0;
69 }
70
mbfl_memory_device_unput(mbfl_memory_device * device)71 void mbfl_memory_device_unput(mbfl_memory_device *device)
72 {
73 if (device->pos > 0) {
74 device->pos--;
75 }
76 }
77
mbfl_memory_device_result(mbfl_memory_device * device,mbfl_string * result)78 mbfl_string* mbfl_memory_device_result(mbfl_memory_device *device, mbfl_string *result)
79 {
80 result->len = device->pos;
81 mbfl_memory_device_output('\0', device);
82 result->val = device->buffer;
83 device->buffer = NULL;
84 device->length = device->pos = 0;
85 return result;
86 }
87
mbfl_memory_device_output(int c,void * data)88 int mbfl_memory_device_output(int c, void *data)
89 {
90 mbfl_memory_device *device = (mbfl_memory_device *)data;
91
92 if (device->pos >= device->length) {
93 /* reallocate buffer */
94
95 if (device->length > SIZE_MAX - device->allocsz) {
96 /* overflow */
97 return -1;
98 }
99
100 size_t newlen = device->length + device->allocsz;
101 device->buffer = erealloc(device->buffer, newlen);
102 device->length = newlen;
103 }
104
105 device->buffer[device->pos++] = (unsigned char)c;
106 return 0;
107 }
108
mbfl_memory_device_strcat(mbfl_memory_device * device,const char * psrc)109 int mbfl_memory_device_strcat(mbfl_memory_device *device, const char *psrc)
110 {
111 return mbfl_memory_device_strncat(device, psrc, strlen(psrc));
112 }
113
mbfl_memory_device_strncat(mbfl_memory_device * device,const char * psrc,size_t len)114 int mbfl_memory_device_strncat(mbfl_memory_device *device, const char *psrc, size_t len)
115 {
116 if (len > device->length - device->pos) {
117 /* reallocate buffer */
118
119 if (len > SIZE_MAX - MBFL_MEMORY_DEVICE_ALLOC_SIZE
120 || device->length > SIZE_MAX - (len + MBFL_MEMORY_DEVICE_ALLOC_SIZE)) {
121 /* overflow */
122 return -1;
123 }
124
125 size_t newlen = device->length + len + MBFL_MEMORY_DEVICE_ALLOC_SIZE;
126 device->buffer = erealloc(device->buffer, newlen);
127 device->length = newlen;
128 }
129
130 unsigned char *w = &device->buffer[device->pos];
131 memcpy(w, psrc, len);
132 device->pos += len;
133
134 return 0;
135 }
136
mbfl_memory_device_devcat(mbfl_memory_device * dest,mbfl_memory_device * src)137 int mbfl_memory_device_devcat(mbfl_memory_device *dest, mbfl_memory_device *src)
138 {
139 return mbfl_memory_device_strncat(dest, (const char*)src->buffer, src->pos);
140 }
141
mbfl_wchar_device_init(mbfl_wchar_device * device)142 void mbfl_wchar_device_init(mbfl_wchar_device *device)
143 {
144 device->buffer = NULL;
145 device->length = 0;
146 device->pos = 0;
147 device->allocsz = MBFL_MEMORY_DEVICE_ALLOC_SIZE;
148 }
149
mbfl_wchar_device_clear(mbfl_wchar_device * device)150 void mbfl_wchar_device_clear(mbfl_wchar_device *device)
151 {
152 if (device->buffer) {
153 efree(device->buffer);
154 }
155 device->buffer = NULL;
156 device->length = device->pos = 0;
157 }
158
mbfl_wchar_device_output(int c,void * data)159 int mbfl_wchar_device_output(int c, void *data)
160 {
161 mbfl_wchar_device *device = (mbfl_wchar_device *)data;
162
163 if (device->pos >= device->length) {
164 /* reallocate buffer */
165 size_t newlen;
166
167 if (device->length > SIZE_MAX - device->allocsz) {
168 /* overflow */
169 return -1;
170 }
171
172 newlen = device->length + device->allocsz;
173 if (newlen > SIZE_MAX / sizeof(int)) {
174 /* overflow */
175 return -1;
176 }
177
178 device->buffer = erealloc(device->buffer, newlen * sizeof(int));
179 device->length = newlen;
180 }
181
182 device->buffer[device->pos++] = c;
183 return 0;
184 }
185