From: Pavel Charvat Date: Wed, 8 Mar 2006 20:46:05 +0000 (+0100) Subject: Slightly faster mp-charconv... minor change X-Git-Tag: holmes-import~662 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=ee58c363f2df512f649ac2837ee06c3cdbc75a03;p=libucw.git Slightly faster mp-charconv... minor change --- diff --git a/charset/mp-charconv.c b/charset/mp-charconv.c index 0235ae76..6976212b 100644 --- a/charset/mp-charconv.c +++ b/charset/mp-charconv.c @@ -2,15 +2,50 @@ * Sherlock Library -- Character Conversion with Allocation on a Memory Pool * * (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" #include "lib/mempool.h" #include "charset/mp-charconv.h" -#include "charset/stk-charconv.h" +#include +#include byte * mp_conv(struct mempool *mp, byte *s, uns in_cs, uns out_cs) { - return mp_strdup(mp, stk_conv(s, in_cs, out_cs)); + if (in_cs == out_cs) + return mp_strdup(mp, s); + + struct conv_context c; + char *b[32]; + uns bs[32], n = 0, sum = 0; + uns l = strlen(s) + 1; + + conv_init(&c); + conv_set_charset(&c, in_cs, out_cs); + c.source = s; + c.source_end = s + l; + + for (;;) + { + l <<= 1; + c.dest_start = c.dest = b[n] = alloca(l); + c.dest_end = c.dest_start+ l; + uns r = conv_run(&c); + sum += bs[n++] = c.dest - c.dest_start; + if (r & CONV_SOURCE_END) + { + c.dest_start = c.dest = mp_alloc(mp, sum); + for (uns i = 0; i < n; i++) + { + memcpy(c.dest, b[i], bs[i]); + c.dest += bs[i]; + } + return c.dest_start; + } + } } + diff --git a/charset/mp-charconv.h b/charset/mp-charconv.h index f3d7bd23..2677c804 100644 --- a/charset/mp-charconv.h +++ b/charset/mp-charconv.h @@ -2,6 +2,9 @@ * Sherlock Library -- Character Conversion with Allocation on a Memory Pool * * (c) 2006 Pavel Charvat + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. */ #ifndef _CHARSET_MP_CHARCONV_H diff --git a/charset/stk-charconv.c b/charset/stk-charconv.c index 10af7211..2dca1c56 100644 --- a/charset/stk-charconv.c +++ b/charset/stk-charconv.c @@ -2,6 +2,9 @@ * 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,50 +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_conv_init(struct conv_context *c, byte *s, uns in_cs, uns out_cs) { uns l = strlen(s); if (in_cs == out_cs) { - c->c.source = s; - c->c.source_end = NULL; - c->len = l + 1; - return; + c->source = s; + c->source_end = NULL; + return l + 1; } - conv_init(&c->c); - conv_set_charset(&c->c, in_cs, out_cs); - c->c.source = s; - c->c.source_end = s + l + 1; + 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->len = INITIAL_MIN_SIZE; + return INITIAL_MIN_SIZE; else - c->len = l * INITIAL_SCALE + 1; - c->len = 1; + return l * INITIAL_SCALE + 1; } -int -stk_conv_step(struct stk_conv_context *c, byte *buf) +uns +stk_conv_step(struct conv_context *c, byte *buf, uns len) { - if (!c->c.source_end) + if (!c->source_end) { - memcpy(buf, c->c.source, c->len); - c->c.dest_start = buf; + memcpy(buf, c->source, len); + c->dest_start = buf; return 0; } - if (c->c.dest_start) + if (c->dest_start) { - uns l = c->c.dest_end - c->c.dest_start; - memcpy(buf, c->c.dest_start, l); - c->c.dest = buf + l; + uns l = c->dest_end - c->dest_start; + memcpy(buf, c->dest_start, l); + c->dest = buf + l; } else - c->c.dest = buf; - c->c.dest_start = buf; - c->c.dest_end = buf + c->len; - if ((conv_run(&c->c) & CONV_SOURCE_END)) + c->dest = buf; + c->dest_start = buf; + c->dest_end = buf + len; + if (conv_run(c) & CONV_SOURCE_END) return 0; - c->len <<= 1; - return 1; + return len << 1; } diff --git a/charset/stk-charconv.h b/charset/stk-charconv.h index a8c6afd8..9f010004 100644 --- a/charset/stk-charconv.h +++ b/charset/stk-charconv.h @@ -2,6 +2,9 @@ * 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. */ #ifndef _CHARSET_STK_CHARCONV_H @@ -13,20 +16,15 @@ /* The following macros convert strings between given charsets (CONV_CHARSET_x). */ #define stk_conv(s, cs_in, cs_out) \ - ({ struct stk_conv_context _c; stk_conv_init(&_c, (s), (cs_in), (cs_out)); \ - while (stk_conv_step(&_c, alloca(_c.len))); _c.c.dest_start; }) + ({ struct conv_context _c; uns _l=stk_conv_init(&_c, (s), (cs_in), (cs_out)); \ + while (_l) _l=stk_conv_step(&_c, alloca(_l), _l); _c.dest_start; }) #define stk_conv_to_utf8(s, cs_in) stk_conv(s, cs_in, CONV_CHARSET_UTF8) #define stk_conv_from_utf8(s, cs_out) stk_conv(s, CONV_CHARSET_UTF8, cs_out) -/* Internal structure and routines. */ - -struct stk_conv_context { - struct conv_context c; - uns len; -}; +/* Internals */ -void stk_conv_init(struct stk_conv_context *c, byte *s, uns cs_in, uns cs_out); -int stk_conv_step(struct stk_conv_context *c, byte *buf); +uns stk_conv_init(struct conv_context *c, byte *s, uns cs_in, uns cs_out); +uns stk_conv_step(struct conv_context *c, byte *buf, uns len); #endif