ftp.nice.ch/pub/next/unix/archiver/freeze.2.3.N.bs.tar.gz#/freeze/lz.c

This is lz.c in view mode; [Download] [Up]

#include "freeze.h"
#include "lz.h"

/*----------------------------------------------------------------------*/
/*                                                                      */
/*                          LZSS ENCODING                               */
/*                                                                      */
/*----------------------------------------------------------------------*/

uchar    text_buf[N2 + F2 - 1];          /* cyclic buffer with an overlay */
u_short   match_position, match_length; /* current characteristics of a
					   matched pattern */

/*      next[N+1..] is used as hash table,
	the rest of next is a link down,
	prev is a link up.
*/

hash_t             prev[N2 + 1];

#ifndef __XENIX__
#ifdef __TURBOC__
u_short huge * next = (u_short huge *) NULL;
#else  /* __TURBOC__ */
u_short next[array_size];       /* a VERY large array :-) */
#endif /* __TURBOC__ */
#else  /* __XENIX__ */
#if parts == 2
u_short next0[32768L], next1[8193];
#else
#       if parts == 3
u_short next0[32768L], next1[32768L], next2[8193];
#       else
#               if parts == 5
u_short next0[32768L], next1[32768L], next2[32768L], next3[32768L], next4[8193];
#               else
u_short next0[32768L], next1[32768L], next2[32768L], next3[32768L], next4[32768L],
	next5[32768L], next6[32768L], next7[32768L], next8[8193];
#               endif
#       endif
#endif  /* parts */

/* A list of `next's parts */

u_short *next[parts] = {
next0, next1
#if parts > 2
,next2
#if parts > 3
,next3, next4
#if parts > 5
,next5, next6,
next7, next8
#endif
#endif
#endif
};
#endif  /* __XENIX__ */

#ifdef GATHER_STAT
long node_steps, node_matches;
#endif  /* GATHER_STAT */

/* Initialize the data structures and allocate memory, if needed.
	Although there is no more trees in the LZ algorithm
	implementation, routine name is kept intact :-)
*/

void InitTree ()
{
	long i;
#ifdef GATHER_STAT
	node_steps = node_matches = 0;
#endif  /* GATHER_STAT */

#ifdef __TURBOC__
	if (!next && (next = (u_short huge *) farmalloc(
		(unsigned long)array_size * sizeof(u_short))) == NULL) {

		fprintf(stderr, "Not enough memory (%luK wanted)\n",
			(unsigned long)array_size * sizeof(u_short) / 1024);
		exit(3);
	}
#endif  /* __TURBOC__ */

	for (i = N2 + 1; i < array_size; i++ )
		nextof(i) = NIL;
	for (i = 0; i < sizeof(prev)/sizeof(*prev); i++ )
		prev[i] = NIL;
}

/* Get the longest nearest match of the string beginning in text_buf[r]
	to the cyclic buffer. Result (length & position) is returned
	in correspondent global variables (`match_length' &
	`match_position'). `match_length' == 0 denotes failure.
*/

#ifndef FAST
void get_next_match (r)
	u_short r;
{
	register u_short p = r;
	register int m;
	register uchar  *key FIX_SI, *pattern FIX_DI;
#ifdef GATHER_STAT
	node_matches++;
#endif
	key = text_buf + r;
	match_length = 0;
	do {
		do {
			if ((p = nextof(p)) == NIL)
				return;
			pattern = text_buf + p;

			MATCHING;

		} while NOT_YET;

#ifdef GATHER_STAT
		node_steps++;
#endif

		for (m = match_length;
			++m < F2 && key[m] == pattern[m]; );

		match_length = m;
		match_position = ((r - p) & (N2 - 1)) - 1;
	} while (m < F2);

/* There are two equal F-char sequences, the oldest one must be
	deleted from the list.
*/


#ifdef DEBUG
	if (verbose)
		fprintf(stderr, "Replacing node: %d -> %d\n", p, r);
#endif
	nextof(prev[p]) = nextof(p);
	prev[nextof(p)] = prev[p];
	prev[p] = NIL;  /* remove p, it is further than r */
	return;
}
#endif

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.