OSDN Git Service

should return value
[lha/olha.git] / io.c
diff --git a/io.c b/io.c
index 6df90b2..d8c9562 100644 (file)
--- a/io.c
+++ b/io.c
@@ -1,18 +1,13 @@
 /***********************************************************
-       io.c -- input/output
+        io.c -- input/output
 ***********************************************************/
 #include "ar.h"
+#include <assert.h>
 
 #define CRCPOLY  0xA001         /* ANSI CRC-16 */
                          /* CCITT: 0x8408 */
 
-FILE *infile, *outfile;
-uint crc;
-ushort bitbuf;
-
 ushort crctable[UCHAR_MAX + 1];
-static uint subbitbuf;
-static int bitcount;
 
 void
 make_crctable(void)
@@ -30,21 +25,72 @@ make_crctable(void)
     }
 }
 
+static const char *
+bitstring(unsigned int bitbuf, int n, char *ptr, size_t sz)
+{
+    static char str[256];
+    size_t size = sz;
+
+    if (ptr == NULL) {
+      ptr = str;
+      size = sizeof(str);
+    }
+
+    if (n+1 > size)
+        return "bit size is too big";
+
+    ptr[n] = '\0';
+
+    while (n > 0) {
+      ptr[--n] = (bitbuf & 1) ? '1' : '0';
+      bitbuf >>= 1;
+    }
+    return ptr;
+}
+
+/*
+  fill bitbuf for reading.
+
+    o shift bitbuf n bits left.
+    o read 8 bits from file and put it to subbitbuf.
+    o get n bits from subbitbuf and fill into bitbuf.
+
+         7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+bitbuf   |                      a b c d e|
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                                already filled at last time.
+                               <--------->
+                                7 6 5 4 3 2 1 0
+                               +-+-+-+-+-+-+-+-+
+                    subbitbuf  |a b c d e 1 1 1|
+                               +-+-+-+-+-+-+-+-+
+                                         <----->
+                                          bitcount (size of subbitbuf data)
+*/
 void
 fillbuf(struct lzh_istream *rp, int n)
-{                               /* Shift bitbuf n bits left, read n bits */
-    bitbuf <<= n;
-    while (n > bitcount) {
-        bitbuf |= subbitbuf << (n -= bitcount);
-        if (compsize != 0) {
-            compsize--;
-            subbitbuf = (uchar) getc(rp->fp);
+{
+    assert(n <= BITBUFSIZ);
+
+    rp->bitbuf <<= n;
+    while (n > rp->bitcount) {
+        /* set bitcount bits from subbitbuf */
+        /* note: subbitbuf << n is extended unsigned int */
+        n -= rp->bitcount;
+        rp->bitbuf |= rp->subbitbuf << n;
+        if (rp->compsize != 0) {
+            rp->compsize--;
+            rp->subbitbuf = (uchar) getc(rp->fp);
         }
         else
-            subbitbuf = 0;
-        bitcount = CHAR_BIT;
+            rp->subbitbuf = 0;
+        rp->bitcount = CHAR_BIT;
     }
-    bitbuf |= subbitbuf >> (bitcount -= n);
+    /* set n bits from subbitbuf */
+    rp->bitcount -= n;
+    rp->bitbuf |= rp->subbitbuf >> rp->bitcount;
 }
 
 uint
@@ -52,7 +98,7 @@ getbits(struct lzh_istream *rp, int n)
 {
     uint x;
 
-    x = bitbuf >> (BITBUFSIZ - n);
+    x = rp->bitbuf >> (BITBUFSIZ - n);
     fillbuf(rp, n);
     return x;
 }
@@ -60,64 +106,67 @@ getbits(struct lzh_istream *rp, int n)
 void
 putbits(struct lzh_ostream *wp, int n, uint x)
 {                               /* Write rightmost n bits of x */
-    if (n < bitcount) {
-        subbitbuf |= x << (bitcount -= n);
+    if (n < wp->bitcount) {
+        wp->subbitbuf |= x << (wp->bitcount -= n);
     }
     else {
-        if (compsize < origsize) {
-            putc(subbitbuf | (x >> (n -= bitcount)), wp->fp);
-            compsize++;
+        if (wp->compsize < wp->origsize) {
+            putc(wp->subbitbuf | (x >> (n -= wp->bitcount)), wp->fp);
+            wp->compsize++;
         }
         else
-            unpackable = 1;
+            wp->unpackable = 1;
         if (n < CHAR_BIT) {
-            subbitbuf = x << (bitcount = CHAR_BIT - n);
+            wp->subbitbuf = x << (wp->bitcount = CHAR_BIT - n);
         }
         else {
-            if (compsize < origsize) {
+            if (wp->compsize < wp->origsize) {
                 putc(x >> (n - CHAR_BIT), wp->fp);
-                compsize++;
+                wp->compsize++;
             }
             else
-                unpackable = 1;
-            subbitbuf = x << (bitcount = 2 * CHAR_BIT - n);
+                wp->unpackable = 1;
+            wp->subbitbuf = x << (wp->bitcount = 2 * CHAR_BIT - n);
         }
     }
 }
 
 int
-fread_crc(void *p, int n, FILE * f)
+fread_crc(void *p, int n, FILE * f, unsigned int *crc)
 {
     int i;
 
     i = n = fread(p, 1, n, f);
-    origsize += n;
-    while (--i >= 0)
-        UPDATE_CRC(*(unsigned char*)p++);
+    if (crc) {
+        while (--i >= 0)
+            UPDATE_CRC(*crc, *(unsigned char*)p++);
+    }
     return n;
 }
 
 void
-fwrite_crc(void *p, int n, FILE * f)
+fwrite_crc(void *p, int n, FILE * f, unsigned int *crc)
 {
     if (fwrite(p, 1, n, f) < n)
         error("Unable to write");
-    while (--n >= 0)
-        UPDATE_CRC(*(unsigned char*)p++);
+    if (crc) {
+        while (--n >= 0)
+            UPDATE_CRC(*crc, *(unsigned char*)p++);
+    }
 }
 
 void
 init_getbits(struct lzh_istream *rp)
 {
-    bitbuf = 0;
-    subbitbuf = 0;
-    bitcount = 0;
+    rp->bitbuf = 0;
+    rp->subbitbuf = 0;
+    rp->bitcount = 0;
     fillbuf(rp, BITBUFSIZ);
 }
 
 void
-init_putbits(void)
+init_putbits(struct lzh_ostream *wp)
 {
-    bitcount = CHAR_BIT;
-    subbitbuf = 0;
+    wp->bitcount = CHAR_BIT;
+    wp->subbitbuf = 0;
 }