X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;ds=sidebyside;f=charset%2Ffb-charconv.c;h=c119a1bea87d55a3ee7855434d9b7b56263bfe40;hb=09e7fe5641b94148d998a1b620bf694f353cb17b;hp=a7ba616f77dc14ed48bb23b0ed7958c4623aa615;hpb=d4bd861a91d3e9d9ed08336e553d5b9d851f1e64;p=libucw.git diff --git a/charset/fb-charconv.c b/charset/fb-charconv.c index a7ba616f..c119a1be 100644 --- a/charset/fb-charconv.c +++ b/charset/fb-charconv.c @@ -1,24 +1,22 @@ /* * 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. */ -#include "lib/lib.h" -#include "lib/fastbuf.h" +#include "ucw/lib.h" +#include "ucw/fastbuf.h" #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) { - bclose(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; +}