X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=charset%2Fstk-charconv.c;h=d5f55fed9e55a599a9e9e8e033ea79c5a8aa06a3;hb=c15baf7b8cf0dc6a07b3c57ad346aee68ac6f19f;hp=2d5c206636feea3fa7e34bb6afe80f99db53eff0;hpb=47fec72b685482a58561be68759e9a8f9059e6b5;p=libucw.git diff --git a/charset/stk-charconv.c b/charset/stk-charconv.c index 2d5c2066..d5f55fed 100644 --- a/charset/stk-charconv.c +++ b/charset/stk-charconv.c @@ -1,7 +1,10 @@ /* - * Sherlock Library -- Character Conversion with Allocation on the Stack + * Sherlock Library -- Character Conversion with Allocation on the Stack * * (c) 2006 Pavel Charvat + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. */ #include "lib/lib.h" @@ -11,87 +14,47 @@ #define INITIAL_MIN_SIZE 16 #define INITIAL_SCALE 2 -void -stk_conv_init(struct stk_conv_context *c, byte *s, uns in_cs, uns out_cs) +uns +stk_strconv_init(struct conv_context *c, byte *s, uns in_cs, uns out_cs) { uns l = strlen(s); - c->count = 0; - - /* For in_cs == out_cs, we emulate stk_strdup */ if (in_cs == out_cs) { - c->size[0] = c->request = l + 1; - c->buf[0] = s; - c->c.source = NULL; - return; + c->source = s; + c->source_end = NULL; + return l + 1; } - - /* Initialization */ - conv_init(&c->c); - conv_set_charset(&c->c, in_cs, out_cs); - c->c.source = s; - c->c.source_end = s + l + 1; - c->sum = 0; - - /* Size of the first buffer */ + conv_init(c); + conv_set_charset(c, in_cs, out_cs); + c->source = s; + c->source_end = s + l + 1; if (l < (INITIAL_MIN_SIZE - 1) / INITIAL_SCALE) - c->request = INITIAL_MIN_SIZE; + return INITIAL_MIN_SIZE; else - c->request = l * INITIAL_SCALE + 1; + return l * INITIAL_SCALE + 1; } -int -stk_conv_step(struct stk_conv_context *c, byte *buf) +uns +stk_strconv_step(struct conv_context *c, byte *buf, uns len) { - /* Merge all buffers to the new one and exit */ - if (!c->c.source) + if (!c->source_end) { - c->c.dest_start = buf; - for (uns i = 0; i <= c->count; i++) - { - memcpy(buf, c->buf[i], c->size[i]); - buf += c->size[i]; - } + memcpy(buf, c->source, len); + c->dest_start = buf; return 0; } - - /* Run conv_run using the new buffer */ - c->buf[c->count] = c->c.dest_start = c->c.dest = buf; - c->c.dest_end = buf + c->request; - if (!(conv_run(&c->c) & CONV_SOURCE_END)) - { - - /* Buffer is too small, continue with a new one */ - c->size[c->count++] = c->request; - c->sum += c->request; - c->request <<= 1; /* This can be freely changed */ - return 1; - } - - /* We have used only one buffer for the conversion, no merges are needed */ - if (!c->count) - return 0; - - /* We can merge everything to the current buffer ... */ - uns s = c->c.dest - c->c.dest_start; - if (c->sum + s <= c->request) + if (c->dest_start) { - memmove(buf + c->sum, buf, s); - for (uns i = 0; i < c->count; i++) - { - memcpy(buf, c->buf[i], c->size[i]); - buf += c->size[i]; - } - return 0; + uns l = c->dest_end - c->dest_start; + memcpy(buf, c->dest_start, l); + c->dest = buf + l; } - - /* ... or we allocate a new one */ else - { - c->request = c->sum + s; - c->size[c->count] = s; - c->c.source = NULL; - return 1; - } + c->dest = buf; + c->dest_start = buf; + c->dest_end = buf + len; + if (conv_run(c) & CONV_SOURCE_END) + return 0; + return len << 1; }