home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************
- io.c -- input/output
- ***********************************************************/
- #include "ar.h"
- #include <stdlib.h>
- #include <stdarg.h>
-
- #define USHRT_BIT (CHAR_BIT * sizeof(ushort))
- #define CRCPOLY 0x8408U /* CCITT */
- #define UPDATE_CRC(c) \
- crc = crctable[(crc ^ (c)) & 0xFF] ^ (crc >> CHAR_BIT)
-
- FILE *arcfile, *infile, *outfile;
- ushort crc, bitbuf;
-
- static ushort crctable[UCHAR_MAX + 1];
- static uchar subbitbuf, bitcount;
-
- void error(char *fmt, ...)
- {
- va_list args;
-
- va_start(args, fmt);
- putc('\n', stderr);
- vfprintf(stderr, fmt, args);
- putc('\n', stderr);
- va_end(args);
- exit(EXIT_FAILURE);
- }
-
- void make_crctable(void)
- {
- uint i, j, r;
-
- for (i = 0; i <= UCHAR_MAX; i++) {
- r = i;
- for (j = 0; j < CHAR_BIT; j++)
- if (r & 1) r = (r >> 1) ^ CRCPOLY;
- else r >>= 1;
- crctable[i] = r;
- }
- }
-
- void fillbuf(uchar n) /* Shift bitbuf n bits left, read n bits */
- {
- while (n > bitcount) {
- n -= bitcount;
- bitbuf = (bitbuf << bitcount) + (subbitbuf >> (CHAR_BIT - bitcount));
- if (compsize != 0) {
- compsize--; subbitbuf = (uchar) getc(arcfile);
- } else subbitbuf = 0;
- bitcount = CHAR_BIT;
- }
- bitcount -= n;
- bitbuf = (bitbuf << n) + (subbitbuf >> (CHAR_BIT - n));
- subbitbuf <<= n;
- }
-
- ushort getbits(uchar n)
- {
- ushort x;
-
- x = bitbuf >> (2 * CHAR_BIT - n); fillbuf(n);
- return x;
- }
-
- #if 0 /* not used in this version */
- void putbit(uchar bit) /* Write 1 bit (bit = 0 or 1) */
- {
- bitcount--;
- if (bit) subbitbuf |= (1U << bitcount);
- if (bitcount == 0) {
- putc(subbitbuf, outfile);
- subbitbuf = 0; bitcount = CHAR_BIT; compsize++;
- }
- }
- #endif
-
- void putbits(uchar n, ushort x) /* Write rightmost n bits of x */
- {
- x <<= USHRT_BIT - n;
- while (n >= bitcount) {
- n -= bitcount;
- subbitbuf += x >> (USHRT_BIT - bitcount);
- x <<= bitcount;
- if (compsize < origsize) {
- putc(subbitbuf, outfile); compsize++;
- } else unpackable = 1;
- subbitbuf = 0; bitcount = CHAR_BIT;
- }
- subbitbuf += x >> (USHRT_BIT - bitcount);
- bitcount -= n;
- }
-
- int fread_crc(uchar *p, int n, FILE *f)
- {
- int i;
-
- i = n = fread(p, 1, n, f); origsize += n;
- while (--i >= 0) UPDATE_CRC(*p++);
- return n;
- }
-
- void fwrite_crc(uchar *p, int n, FILE *f)
- {
- if (fwrite(p, 1, n, f) < n) error("Unable to write");
- while (--n >= 0) UPDATE_CRC(*p++);
- }
-
- void init_getbits(void)
- {
- bitbuf = 0; subbitbuf = 0; bitcount = 0;
- fillbuf(2 * CHAR_BIT);
- }
-
- void init_putbits(void)
- {
- bitcount = CHAR_BIT; subbitbuf = 0;
- }