2 * Sherlock Library -- Character Conversion with Allocation on the Stack
4 * (c) 2006 Pavel Charvat <pchar@ucw.cz>
8 #include "charset/stk-charconv.h"
11 #define INITIAL_MIN_SIZE 16
12 #define INITIAL_SCALE 2
15 stk_conv_init(struct stk_conv_context *c, byte *s, uns in_cs, uns out_cs)
20 /* For in_cs == out_cs, we emulate stk_strdup */
23 c->size[0] = c->request = l + 1;
31 conv_set_charset(&c->c, in_cs, out_cs);
33 c->c.source_end = s + l + 1;
36 /* Size of the first buffer */
37 if (l < (INITIAL_MIN_SIZE - 1) / INITIAL_SCALE)
38 c->request = INITIAL_MIN_SIZE;
40 c->request = l * INITIAL_SCALE + 1;
44 stk_conv_step(struct stk_conv_context *c, byte *buf)
46 /* Merge all buffers to the new one and exit */
49 c->c.dest_start = buf;
50 for (uns i = 0; i <= c->count; i++)
52 memcpy(buf, c->buf[i], c->size[i]);
58 /* Run conv_run using the new buffer */
59 c->buf[c->count] = c->c.dest_start = c->c.dest = buf;
60 c->c.dest_end = buf + c->request;
61 if (!(conv_run(&c->c) & CONV_SOURCE_END))
64 /* Buffer is too small, continue with a new one */
65 c->size[c->count++] = c->request;
67 c->request <<= 1; /* This can be freely changed */
71 /* We have used only one buffer for the conversion, no merges are needed */
75 /* We can merge everything to the current buffer ... */
76 uns s = c->c.dest - c->c.dest_start;
77 if (c->sum + s <= c->request)
79 memmove(buf + c->sum, buf, s);
80 for (uns i = 0; i < c->count; i++)
82 memcpy(buf, c->buf[i], c->size[i]);
88 /* ... or we allocate a new one */
91 c->request = c->sum + s;
92 c->size[c->count] = s;