]> mj.ucw.cz Git - libucw.git/blobdiff - charset/fb-charconv.c
Strings: Converted to size_t.
[libucw.git] / charset / fb-charconv.c
index 9c54c883779daa84262fc14b009ba99de4340ff6..252e899466db82d1c46d3ef6e50d754e5ed7ba32 100644 (file)
@@ -1,28 +1,26 @@
 /*
  *     Sherlock Library -- Charset Conversion Wrapper for Fast Buffered I/O
  *
- *     (c) 2003 Martin Mares <mj@ucw.cz>
+ *     (c) 2003--2005 Martin Mares <mj@ucw.cz>
  *
  *     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 "charset/charconv.h"
-#include "charset/fb-charconv.h"
-
-#include <stdlib.h>
+#include <ucw/lib.h>
+#include <ucw/fastbuf.h>
+#include <charset/charconv.h>
+#include <charset/fb-charconv.h>
 
 #define BUFSIZE 1024
 
 struct fb_charconv {
   struct fastbuf fb;
-  struct fastbuf *out;
+  struct fastbuf *orig;
   struct conv_context ctxt;
   byte buf[BUFSIZE];
 };
-#define FB_CC(f) ((struct fb_charconv *)(f)->is_fastbuf)
+#define FB_CC(f) ((struct fb_charconv *)(f))
 
 static void
 fb_cc_spout(struct fastbuf *f)
@@ -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 = "<charconv-out>";
@@ -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 = "<charconv-in>";
+  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;
+}