Path: utzoo!attcan!uunet!blkcat!p0.f40.n109.z1.fidonet.org!Kai-Uwe.Rommel From: Kai-Uwe.Rommel@p0.f40.n109.z1.fidonet.org (Kai-Uwe Rommel) Newsgroups: comp.os.os2 Subject: (Part 5) compress (fast!) for OS/2 Message-ID: <723.25FAE6FF@blkcat.fidonet.org> Date: 12 Mar 90 04:39:48 GMT Sender: ufgate@blkcat.fidonet.org (newsout1.26) Organization: FidoNet node 1:109/40.0 - Crewe 400 Nat'l Hub, Joe Keenan Lines: 174 *** Split Message, part #5, MsgSplit Version 2 (11-Mar-90) *** X if ((size = fread(bitbuf, 1, n_bits, stdin)) <= 0) X break; X /* Round size down to integral number of codes */ X size = (size << 3) - (n_bits - 1); X bitoff = 0; X } X /* X * Read the next code into "code". On the 8088, X * a slight speedup is possible because it has the right byte X * order, and no alignment restrictions. X */ X#ifdef i8088 X code = ((code_t)(*(long *)&bitbuf[(bitoff >> 3)] >> X (bitoff&7))) & codemask; X#else X bp = &bitbuf[(bitoff >> 3)]; X code = (code_t)(((bp[0] | (code_t)bp[1] << 8) | X (ulong)bp[2] << 16) >> (bitoff & 7)) & codemask; X#endif X bitoff += n_bits; X X if ((code == CLEAR) && block_compress) { X n_bits = INIT_BITS; X maxcode = MAXCODE(INIT_BITS) - 1; X codemask = MAXCODE(INIT_BITS); X freecode = (FIRST - 1) - 1; X size = 0; X continue; X } X incode = code; X X /* X * Special case for KwKwK string. X */ X if (code > freecode) { X if (code != freecode + 1) X oops(); X *stackp++ = (uchar)finchar; X code = oldcode; X } X X /* X * Generate output characters in reverse order X */ X while (code >= 256) { X *stackp++ = de_suffixof(code); X code = de_prefixof(code); X } X X /* X * And write them out in the forward order. X */ X putchar(finchar = code); X for (code = (stackp - de_stack) + 1; --code != 0; ) X putchar(*--stackp); X X /* X * Generate the new entry. X */ X if (freecode < maxmaxcode) { X if (++freecode > maxcode) { X if (++n_bits == maxbits) X maxcode = maxmaxcode; X else X maxcode = MAXCODE(n_bits) - 1; X size = 0; X codemask = MAXCODE(n_bits); X } X de_prefixof(freecode) = oldcode; X de_suffixof(freecode) = (uchar)finchar; X } X /* X * Remember previous code. X */ X oldcode = incode; X } X fflush(stdout); X if (ferror(stdout)) X writeerr(); X} X X/* X * Check a compressed file to make sure it has the proper magic number X * at the beginning. Also read the third byte to determine "maxbits", X * and "block_compress". X */ Xint check_magic() X{ X if (! magic) X return (1); X if ((getchar() != MAGIC0) || (getchar() != MAGIC1)) { X fprintf(stderr, "%s: not in compressed format\n", ifname); X return (0); X } X maxbits = getchar(); /* set -b from file */ X block_compress = maxbits & BLOCK_MASK; X maxbits &= BIT_MASK; X if (maxbits > BITS) { X fprintf(stderr, X "%s: compressed with %d bits, can only handle %d bits\n", X ifname, maxbits, BITS); X return (0); X } X return (1); X} X Xvoid writeerr() X{ X perror(ofname); X fclose(stdout); X unlink(ofname); X exit(1); X} X X/* X * Copy the permissions and file times from the input file to the X * output. X */ Xvoid copystat() X{ X struct stat statbuf; X int mode; X void (* ss)(); X#ifndef __TURBOC__ X time_t timep[2]; X#else X struct ftime filetime; X int fd; X#endif X X fclose(stdout); X if (stat(ifname, &statbuf)) { /* Get stat on input file */ X perror(ifname); X return; X } X if ((statbuf.st_mode & S_IFMT) != S_IFREG) { X if (! verbose) X fprintf(stderr, "%s: ", ifname); X fprintf(stderr, " -- not a regular file: unchanged"); X exit_stat = 1; X } X else if (statbuf.st_nlink > 1) { X if (! verbose) X fprintf(stderr, "%s: ", ifname); X fprintf(stderr, " -- has %d other links: unchanged", X statbuf.st_nlink - 1); X exit_stat = 1; X } X else if (exit_stat == 2 && !force) { /* No compression: remove file.Z */ X if (verbose) X fprintf(stderr, " -- file unchanged"); X } X else { /* ***** Successful Compression ***** */ X exit_stat = 0; X mode = statbuf.st_mode & 07777; X#ifndef __ZTC__ X if (chmod(ofname, mode)) /* Copy modes */ X perror(ofname); X#endif X#ifndef MSDOS *** Original message split, continued in next message *** e -- Kai-Uwe Rommel at The Black Cat's Shack (Fidonet 1:109/401) Internet: Kai-Uwe.Rommel@p0.f40.n109.z1.fidonet.org UUCP: ...!uunet!blkcat!40.0!Kai-Uwe.Rommel