X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=charset%2Ffb-charconv.c;h=1d46005187f3f05e931e779b68cc9168ea81bf0e;hb=67d52e562eaeef76ee6c5d9f8ca2da573e825506;hp=9c54c883779daa84262fc14b009ba99de4340ff6;hpb=3f83b476bea040d4c35c710331dcd979f86ddf38;p=libucw.git diff --git a/charset/fb-charconv.c b/charset/fb-charconv.c index 9c54c883..1d460051 100644 --- a/charset/fb-charconv.c +++ b/charset/fb-charconv.c @@ -1,7 +1,7 @@ /* * Sherlock Library -- Charset Conversion Wrapper for Fast Buffered I/O * - * (c) 2003 Martin Mares + * (c) 2003--2005 Martin Mares * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. @@ -12,13 +12,11 @@ #include "charset/charconv.h" #include "charset/fb-charconv.h" -#include - #define BUFSIZE 1024 struct fb_charconv { struct fastbuf fb; - struct fastbuf *out; + struct fastbuf *orig; struct conv_context ctxt; byte buf[BUFSIZE]; }; @@ -36,8 +34,8 @@ fb_cc_spout(struct fastbuf *f) { flags = conv_run(ct); if (ct->dest > ct->dest_start) - bdirect_write_commit(FB_CC(f)->out, ct->dest); - uns l = bdirect_write_prepare(FB_CC(f)->out, &ct->dest_start); + bdirect_write_commit(FB_CC(f)->orig, ct->dest); + uns l = bdirect_write_prepare(FB_CC(f)->orig, &ct->dest_start); ct->dest = ct->dest_start; ct->dest_end = ct->dest + l; } @@ -46,10 +44,35 @@ fb_cc_spout(struct fastbuf *f) f->bptr = f->buffer; } +static int +fb_cc_refill(struct fastbuf *f) +{ + struct conv_context *ct = &FB_CC(f)->ctxt; + int flags; + + f->bptr = f->bstop = f->buffer; + do + { + byte *src; + uns len = bdirect_read_prepare(FB_CC(f)->orig, &src); + if (!len) + break; + ct->source = src; + ct->source_end = ct->source + len; + ct->dest = ct->dest_start = f->bstop; + ct->dest_end = f->bufend; + flags = conv_run(ct); + bdirect_read_commit(FB_CC(f)->orig, (byte*)ct->source); + f->bstop = ct->dest; + } + while (!(flags & CONV_DEST_END)); + return (f->bstop > f->bptr); +} + static void fb_cc_close(struct fastbuf *f) { - bflush(FB_CC(f)->out); + bflush(FB_CC(f)->orig); xfree(f); } @@ -60,7 +83,7 @@ fb_wrap_charconv_out(struct fastbuf *f, int cs_from, int cs_to) return f; struct fastbuf *g = xmalloc_zero(sizeof(struct fb_charconv)); - FB_CC(g)->out = f; + FB_CC(g)->orig = f; conv_init(&FB_CC(g)->ctxt); conv_set_charset(&FB_CC(g)->ctxt, cs_from, cs_to); g->name = ""; @@ -70,3 +93,21 @@ fb_wrap_charconv_out(struct fastbuf *f, int cs_from, int cs_to) g->bufend = g->buffer + BUFSIZE; return g; } + +struct fastbuf * +fb_wrap_charconv_in(struct fastbuf *f, int cs_from, int cs_to) +{ + if (cs_from == cs_to) + return f; + + struct fastbuf *g = xmalloc_zero(sizeof(struct fb_charconv)); + FB_CC(g)->orig = f; + conv_init(&FB_CC(g)->ctxt); + conv_set_charset(&FB_CC(g)->ctxt, cs_from, cs_to); + g->name = ""; + g->refill = fb_cc_refill; + g->close = fb_cc_close; + g->buffer = g->bstop = g->bptr = FB_CC(g)->buf; + g->bufend = g->buffer + BUFSIZE; + return g; +}