/***********************************************************
- 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)
}
}
+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
{
uint x;
- x = bitbuf >> (BITBUFSIZ - n);
+ x = rp->bitbuf >> (BITBUFSIZ - n);
fillbuf(rp, n);
return x;
}
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;
}