X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;ds=inline;f=charset%2Fstk-charconv.c;h=853bd9db03c06607c5ed68b588baead2df77269f;hb=dbe3b315edac25079fcbfe4df20e80b534f2a7a1;hp=6550ea351b6cdd7f25ec91da9d36d3b7f7ac01ce;hpb=7af80cdb684884505ceeb2d71414b2b9c24ab02b;p=libucw.git diff --git a/charset/stk-charconv.c b/charset/stk-charconv.c index 6550ea35..853bd9db 100644 --- a/charset/stk-charconv.c +++ b/charset/stk-charconv.c @@ -1,32 +1,60 @@ /* - * 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" +#include "ucw/lib.h" #include "charset/stk-charconv.h" #include +#define INITIAL_MIN_SIZE 16 +#define INITIAL_SCALE 2 + uns -stk_conv_internal(struct conv_context *c, byte *s, uns in_cs, uns out_cs) +stk_strconv_init(struct conv_context *c, const byte *s, uns in_cs, uns out_cs) { - /* We do not allocate anything for identical charsets. */ - if (in_cs == out_cs) - { - c->dest_start = s; - return 0; - } - uns l = strlen(s); - + if (in_cs == out_cs) + { + c->source = s; + c->source_end = NULL; + return 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) + return INITIAL_MIN_SIZE; + else + return l * INITIAL_SCALE + 1; +} - /* Resulting string can be longer after the conversion. - * The following constatnt must be at least 4 for conversion to UTF-8 - * and at least the maximum length of the strings in string_table for other charsets. */ - return 4 * l + 1; +uns +stk_strconv_step(struct conv_context *c, byte *buf, uns len) +{ + if (!c->source_end) + { + memcpy(buf, c->source, len); + c->dest_start = buf; + return 0; + } + if (c->dest_start) + { + uns l = c->dest_end - c->dest_start; + memcpy(buf, c->dest_start, l); + c->dest = buf + l; + } + else + c->dest = buf; + c->dest_start = buf; + c->dest_end = buf + len; + if (conv_run(c) & CONV_SOURCE_END) + return 0; + return len << 1; } +