blob: e6ba5f38dd4ae93bb25e80c66cfeb507ddd1aaf5 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001#ifdef UEMF
2 #include "uemf.h"
3#else
4 #include "basic/basicInternal.h"
5#endif
6
7static int getBinBlockSize(int size);
8static int ringqGrow(ringq_t *rq);
9
10#define RINGQ_LEN(rq) \
11 ((rq->servp > rq->endp) ? \
12 (rq->buflen + (rq->endp - rq->servp)) : \
13 (rq->endp - rq->servp))
14
15
16
17int ringqGrowCalls = 0;
18
19int ringqOpen(ringq_t *rq, int initSize, int maxsize)
20{
21 int increment;
22
23 a_assert(rq);
24 a_assert(initSize >= 0);
25
26 increment = getBinBlockSize(initSize);
27 if ((rq->buf = balloc(B_L, (increment))) == NULL) {
28 return -1;
29 }
30 rq->maxsize = maxsize;
31 rq->buflen = increment;
32 rq->increment = increment;
33 rq->endbuf = &rq->buf[rq->buflen];
34 rq->servp = rq->buf;
35 rq->endp = rq->buf;
36 *rq->servp = '\0';
37 return 0;
38}
39
40int ringqInsertc(ringq_t *rq, char_t c)
41{
42 char_t *cp;
43
44 a_assert(rq);
45 a_assert(rq->buflen == (rq->endbuf - rq->buf));
46
47 if (ringqPutBlkMax(rq) < (int) sizeof(char_t) && !ringqGrow(rq)) {
48 return -1;
49 }
50 if (rq->servp <= rq->buf) {
51 rq->servp = rq->endbuf;
52 }
53 cp = (char_t*) rq->servp;
54 *--cp = (char_t) c;
55 rq->servp = (unsigned char *) cp;
56 return 0;
57}
58
59int ringqPutc(ringq_t *rq, char_t c)
60{
61 char_t *cp;
62
63 a_assert(rq);
64 a_assert(rq->buflen == (rq->endbuf - rq->buf));
65
66 if ((ringqPutBlkMax(rq) < (int) sizeof(char_t)) && !ringqGrow(rq)) {
67 return -1;
68 }
69
70 cp = (char_t*) rq->endp;
71 *cp++ = (char_t) c;
72 rq->endp = (unsigned char *) cp;
73 if (rq->endp >= rq->endbuf) {
74 rq->endp = rq->buf;
75 }
76 return 0;
77}
78
79int ringqGetc(ringq_t *rq)
80{
81 char_t c;
82 char_t* cp;
83
84 a_assert(rq);
85 a_assert(rq->buflen == (rq->endbuf - rq->buf));
86
87 if (rq->servp == rq->endp) {
88 return -1;
89 }
90
91 cp = (char_t*) rq->servp;
92 c = *cp++;
93 rq->servp = (unsigned char *) cp;
94 if (rq->servp >= rq->endbuf) {
95 rq->servp = rq->buf;
96 }
97 return (int) ((unsigned char) c);
98}
99
100int ringqLen(ringq_t *rq)
101{
102 a_assert(rq);
103 a_assert(rq->buflen == (rq->endbuf - rq->buf));
104
105 if (rq->servp > rq->endp) {
106 return rq->buflen + rq->endp - rq->servp;
107 } else {
108 return rq->endp - rq->servp;
109 }
110}
111
112void ringqAddNull(ringq_t *rq)
113{
114 a_assert(rq);
115 a_assert(rq->buflen == (rq->endbuf - rq->buf));
116
117 *((char_t*) rq->endp) = (char_t) '\0';
118}
119
120int ringqPutStr(ringq_t *rq, char_t *str)
121{
122 int rc;
123
124 a_assert(rq);
125 a_assert(str);
126 a_assert(rq->buflen == (rq->endbuf - rq->buf));
127
128 rc = ringqPutBlk(rq, (unsigned char*) str, gstrlen(str) * sizeof(char_t));
129 *((char_t*) rq->endp) = (char_t) '\0';
130 return rc;
131}
132
133
134void ringqClose(ringq_t *rq)
135{
136 a_assert(rq);
137 a_assert(rq->buflen == (rq->endbuf - rq->buf));
138
139 if (rq == NULL) {
140 return;
141 }
142
143 ringqFlush(rq);
144 bfree(B_L, (char*) rq->buf);
145 rq->buf = NULL;
146}
147
148
149void ringqFlush(ringq_t *rq)
150{
151 a_assert(rq);
152 a_assert(rq->servp);
153
154 rq->servp = rq->buf;
155 rq->endp = rq->buf;
156 if (rq->servp) {
157 *rq->servp = '\0';
158 }
159}
160
161
162#ifdef UNICODE
163int ringqPutStrA(ringq_t *rq, char *str)
164{
165 int rc;
166
167 a_assert(rq);
168 a_assert(str);
169 a_assert(rq->buflen == (rq->endbuf - rq->buf));
170
171 rc = ringqPutBlk(rq, (unsigned char*) str, strlen(str));
172 rq->endp[0] = '\0';
173 return rc;
174}
175
176int ringqGetcA(ringq_t *rq)
177{
178 unsigned char c;
179
180 a_assert(rq);
181 a_assert(rq->buflen == (rq->endbuf - rq->buf));
182
183 if (rq->servp == rq->endp) {
184 return -1;
185 }
186
187 c = *rq->servp++;
188 if (rq->servp >= rq->endbuf) {
189 rq->servp = rq->buf;
190 }
191 return c;
192}
193
194int ringqInsertcA(ringq_t *rq, char c)
195{
196 a_assert(rq);
197 a_assert(rq->buflen == (rq->endbuf - rq->buf));
198
199 if (ringqPutBlkMax(rq) == 0 && !ringqGrow(rq)) {
200 return -1;
201 }
202 if (rq->servp <= rq->buf) {
203 rq->servp = rq->endbuf;
204 }
205 *--rq->servp = (unsigned char) c;
206 return 0;
207}
208
209int ringqPutcA(ringq_t *rq, char c)
210{
211 a_assert(rq);
212 a_assert(rq->buflen == (rq->endbuf - rq->buf));
213
214 if (ringqPutBlkMax(rq) == 0 && !ringqGrow(rq)) {
215 return -1;
216 }
217
218 *rq->endp++ = (unsigned char) c;
219 if (rq->endp >= rq->endbuf) {
220 rq->endp = rq->buf;
221 }
222 return 0;
223}
224
225#endif /* UNICODE */
226
227void ringqGetBlkAdj(ringq_t *rq, int size)
228{
229 a_assert(rq);
230 a_assert(rq->buflen == (rq->endbuf - rq->buf));
231 a_assert(0 < size && size < rq->buflen);
232
233 rq->servp += size;
234 if (rq->servp >= rq->endbuf) {
235 rq->servp -= rq->buflen;
236 }
237
238 if (rq->servp >= rq->endbuf) {
239 error(E_L, E_LOG, T("Bad serv pointer"));
240 ringqFlush(rq);
241 }
242}
243
244int ringqGetBlkMax(ringq_t *rq)
245{
246 int len, in_a_line;
247
248 a_assert(rq);
249 a_assert(rq->buflen == (rq->endbuf - rq->buf));
250
251 len = RINGQ_LEN(rq);
252 in_a_line = rq->endbuf - rq->servp;
253
254 return min(in_a_line, len);
255}
256
257int ringqGetBlk(ringq_t *rq, unsigned char *buf, int size)
258{
259 int this, bytes_read;
260
261 a_assert(rq);
262 a_assert(rq->buflen == (rq->endbuf - rq->buf));
263 a_assert(buf);
264 a_assert(0 <= size && size < rq->buflen);
265
266 bytes_read = 0;
267 while (size > 0) {
268 this = ringqGetBlkMax(rq);
269 this = min(this, size);
270 if (this <= 0) {
271 break;
272 }
273
274 memcpy(buf, rq->servp, this);
275 buf += this;
276 rq->servp += this;
277 size -= this;
278 bytes_read += this;
279
280 if (rq->servp >= rq->endbuf) {
281 rq->servp = rq->buf;
282 }
283 }
284 return bytes_read;
285}
286
287int ringqPutBlk(ringq_t *rq, unsigned char *buf, int size)
288{
289 int this, bytes_put;
290
291 a_assert(rq);
292 a_assert(rq->buflen == (rq->endbuf - rq->buf));
293 a_assert(buf);
294 a_assert(0 <= size);
295
296 bytes_put = 0;
297 while (size > 0) {
298 this = min(ringqPutBlkMax(rq), size);
299 if (this <= 0) {
300 if (! ringqGrow(rq)) {
301 break;
302 }
303 this = min(ringqPutBlkMax(rq), size);
304 }
305
306 memcpy(rq->endp, buf, this);
307 buf += this;
308 rq->endp += this;
309 size -= this;
310 bytes_put += this;
311
312 if (rq->endp >= rq->endbuf) {
313 rq->endp = rq->buf;
314 }
315 }
316 return bytes_put;
317}
318
319
320int ringqPutBlkMax(ringq_t *rq)
321{
322 int space, in_a_line;
323
324 a_assert(rq);
325 a_assert(rq->buflen == (rq->endbuf - rq->buf));
326
327 space = rq->buflen - RINGQ_LEN(rq) - 1;
328 in_a_line = rq->endbuf - rq->endp;
329
330 return min(in_a_line, space);
331}
332
333
334void ringqPutBlkAdj(ringq_t *rq, int size)
335{
336 a_assert(rq);
337 a_assert(rq->buflen == (rq->endbuf - rq->buf));
338 a_assert(0 <= size && size < rq->buflen);
339
340 rq->endp += size;
341 if (rq->endp >= rq->endbuf) {
342 rq->endp -= rq->buflen;
343 }
344
345 if (rq->endp >= rq->endbuf) {
346 error(E_L, E_LOG, T("Bad end pointer"));
347 ringqFlush(rq);
348 }
349}
350
351
352
353static int ringqGrow(ringq_t *rq)
354{
355 int rq_len;
356 unsigned char *reall_buf;
357
358
359 a_assert(rq);
360
361 if (rq->maxsize >= 0 && rq->buflen >= rq->maxsize) {
362 return 0;
363 }
364
365 rq_len = ringqLen(rq);
366
367 if ((reall_buf = balloc(B_L, rq->buflen + rq->increment)) == NULL) {
368 return 0;
369 }
370 ringqGetBlk(rq, reall_buf, ringqLen(rq));
371 bfree(B_L, (char*) rq->buf);
372
373#ifdef OLD
374 rq->endp = &reall_buf[endp];
375 rq->servp = &reall_buf[servp];
376 rq->endbuf = &reall_buf[rq->buflen];
377 rq->buf = reall_buf;
378#endif
379
380 rq->buflen += rq->increment;
381 rq->endp = reall_buf;
382 rq->servp = reall_buf;
383 rq->buf = reall_buf;
384 rq->endbuf = &rq->buf[rq->buflen];
385
386 ringqPutBlk(rq, reall_buf, rq_len);
387
388 rq->increment = getBinBlockSize(2 * rq->increment);
389
390 return 1;
391}
392
393static int getBinBlockSize(int size)
394{
395 int q;
396
397 size = size >> B_SHIFT;
398 for (q = 0; size; size >>= 1) {
399 q++;
400 }
401 return (1 << (B_SHIFT + q));
402}
403