Hpux: -lcma
BSD: none
-SFIO DISCIPLINES:
-
-IO disciplines allow applications to extend stream data processing.
-See the Sfio manual pages for detail on creating discipline structures
-and inserting them into streams. The directory Sfio_dc contains a number
-of useful disciplines, including one to uncompress a file compressed
-by the Unix compress program and one to make reading DOS text files more
-comfortable by translating \r\n to \n.
-
-Disciplines are reusable code, please contribute any interesting disciplines
-that you come up with. This is best done by sending such code to me at
-the address below. Sharing reusable code means that the name space must
-be managed. Therefore, I recommend that each discipline package provides
-the following public interface:
-
-Sfdisc_t* sfdcXXX(Sfio_t* f, other arguments):
- Create a discipline of the type XXX and insert it into the
- stream f. For example, the below call create a discipline that
- make the stream "f" act as if it's the union of the "n" streams
- given in "array".
- sfdcunion(Sfio_t* f, Sfio_t** array, int n);
-
CORRESPONDENCE:
Comments, etc. should be sent to:
+++ /dev/null
-# $Id$ $Revision$
-## Process this file with automake to produce Makefile.in
-
-AM_CPPFLAGS = -I$(top_srcdir)/lib
-
-noinst_HEADERS = sfdchdr.h sfdisc.h
-noinst_LTLIBRARIES = libsfiodc_C.la
-
-libsfiodc_C_la_SOURCES = sfdcdos.c sfdcfilter.c sfdclzw.c \
- sfdcsubstream.c sfdctee.c sfdcunion.c
-
-${top_builddir}/FEATURE/sfio: ${top_srcdir}/lib/sfio/features/sfio
- mkdir -p ${top_builddir}/FEATURE
- $(top_srcdir)/iffe - set cc $(CC) $(CCMODE) $(CXFLAGS) : run ${top_srcdir}/lib/sfio/features/sfio > $@
-
-$(libsfiodc_C_la_OBJECTS): ${top_builddir}/FEATURE/sfio
-
-DISTCLEANFILES = ${top_builddir}/FEATURE/sfio
+++ /dev/null
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/*************************************************************************
- * Copyright (c) 2011 AT&T Intellectual Property
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: See CVS logs. Details at http://www.graphviz.org/
- *************************************************************************/
-
-#include <sfio/sfdchdr.h>
-
-/* Discipline to turn \r\n into \n.
-** This is useful to deal with DOS text files.
-**
-** Written by David Korn (03/18/1998).
-*/
-
-#define MINMAP 8
-#define CHUNK 1024
-
-struct map {
- off_t logical;
- off_t physical;
-};
-
-typedef struct _dosdisc {
- Sfdisc_t disc;
- struct map *maptable;
- int mapsize;
- int maptop;
- off_t lhere;
- off_t llast;
- off_t lmax;
- off_t pmax;
- off_t phere;
- off_t plast;
- off_t begin;
- int skip;
- void *buff;
- char last;
- char extra;
- int bsize;
-} Dosdisc_t;
-
-static void addmapping(Dosdisc_t * dp)
-{
- int n;
- if ((n = dp->maptop++) >= dp->mapsize) {
- dp->mapsize *= 2;
- if (!
- (dp->maptable =
- (struct map *) realloc((void *) dp->maptable,
- (dp->mapsize +
- 1) * sizeof(struct map)))) {
- dp->maptop--;
- dp->mapsize *= 2;
- return;
- }
- }
- dp->maptable[n].physical = dp->phere;
- dp->maptable[n].logical = dp->lhere;
- dp->maptable[dp->maptop].logical = 0;
-}
-
-static struct map *getmapping(Dosdisc_t * dp, off_t offset,
- int whence)
-{
- struct map *mp;
- static struct map dummy;
- if (offset <= dp->begin) {
- dummy.logical = dummy.physical = offset;
- return (&dummy);
- }
- if (!(mp = dp->maptable)) {
- dummy.logical = dp->begin;
- dummy.physical = dummy.logical + 1;
- return (&dummy);
- }
- while ((++mp)->logical
- && (whence == SEEK_CUR ? mp->physical : mp->logical) <= offset);
- return (mp - 1);
-}
-
-static ssize_t dos_read(Sfio_t * iop, void *buff, size_t size,
- Sfdisc_t * disc)
-{
- Dosdisc_t *dp = (Dosdisc_t *) disc;
- char *cp = (char *) buff, *first, *cpmax;
- int n, count, m;
- if (dp->extra) {
- dp->extra = 0;
- *cp = dp->last;
- return (1);
- }
- while (1) {
- if ((n = sfrd(iop, buff, size, disc)) <= 0)
- return (n);
- dp->plast = dp->phere;
- dp->phere += n;
- dp->llast = dp->lhere;
- cpmax = cp + n - 1;
- if (dp->last == '\r' && *cp != '\n') {
- /* should insert a '\r' */ ;
- }
- dp->last = *cpmax;
- if (n > 1)
- break;
- if (dp->last != '\r') {
- dp->lhere++;
- return (1);
- }
- }
- if (dp->last == '\r')
- n--;
- else if (dp->last != '\n' || cpmax[-1] != '\r')
- *cpmax = '\r';
- dp->lhere += n;
- while (1) {
- while (*cp++ != '\r');
- if (cp > cpmax || *cp == '\n')
- break;
- }
- dp->skip = cp - 1 - (char *) buff;
- /* if not \r\n in buffer, just return */
- if ((count = cpmax + 1 - cp) <= 0) {
- *cpmax = dp->last;
- if (!dp->maptable)
- dp->begin += n;
- dp->skip++;
- count = 0;
- goto done;
- }
- if (!dp->maptable) {
- dp->begin += cp - (char *) buff - 1;
- if ((dp->maptable =
- (struct map *) malloc((MINMAP + 1) * sizeof(struct map)))) {
- dp->mapsize = MINMAP;
- dp->maptable[0].logical = dp->begin;
- dp->maptable[0].physical = dp->maptable[0].logical + 1;
- dp->maptable[1].logical = 0;
- dp->maptop = 1;
- }
- }
- /* save original discipline inside buffer */
- if (count > dp->bsize) {
- if (dp->bsize == 0)
- dp->buff = malloc(count);
- else
- dp->buff = realloc(dp->buff, count);
- dp->bsize = count;
- if (!dp->buff)
- return (-1);
- }
- memcpy(dp->buff, cp, count);
- count = 1;
- while (1) {
- first = cp;
- if (cp == cpmax)
- cp++;
- else
- while (*cp++ != '\r');
- if (cp <= cpmax && *cp != '\n')
- continue;
- if ((m = (cp - first) - 1) > 0)
- memcpy(first - count, first, m);
- if (cp > cpmax)
- break;
- count++;
- }
- cpmax[-count] = dp->last;
- dp->lhere -= count;
- done:
- if (dp->lhere > dp->lmax) {
- dp->lmax = dp->lhere;
- dp->pmax = dp->phere;
- if (dp->maptable
- && dp->lmax > dp->maptable[dp->maptop - 1].logical + CHUNK)
- addmapping(dp);
- }
- return (n - count);
-}
-
-/*
- * returns the current offset
- * <offset> must be in the current buffer
- * if <whence> is SEEK_CUR, physical offset converted to logical offset
- * otherwise, logical offset is converted to physical offset
- */
-static off_t cur_offset(Dosdisc_t * dp, off_t offset, Sfio_t * iop,
- int whence)
-{
- off_t n, m = 0;
- char *cp;
-
- if (whence == SEEK_CUR) {
- whence = -1;
- n = offset - dp->plast;
- iop->next = iop->data + n;
- offset = dp->llast;
- } else {
- whence = 1;
- n = offset - dp->llast;
- offset = dp->plast;
- }
- offset += n;
- if ((n -= dp->skip) > 0) {
- m = whence;
- cp = (char *) dp->buff;
- while (n--) {
- if (*cp++ == '\r' && *cp == '\n') {
- m += whence;
- if (whence > 0)
- n++;
- }
- }
- }
- if (whence < 0)
- iop->next += m;
- return (offset + m);
-}
-
-static Sfoff_t dos_seek(Sfio_t * iop, Sfoff_t offset, int whence,
- Sfdisc_t * disc)
-{
- Dosdisc_t *dp = (Dosdisc_t *) disc;
- struct map dummy, *mp = 0;
- off_t physical;
- int n, size;
- retry:
- switch (whence) {
- case SEEK_CUR:
- offset = sfsk(iop, (off_t) 0, SEEK_CUR, disc);
- if (offset <= dp->begin)
- return (offset);
- /* check for seek outside buffer */
- if (offset == dp->phere)
- return (dp->lhere);
- else if (offset == dp->plast)
- return (dp->llast);
- else if (offset < dp->plast || offset > dp->phere)
- mp = getmapping(dp, offset, whence);
- break;
- case SEEK_SET:
- /* check for seek outside buffer */
- if (offset < dp->llast || offset > dp->lhere)
- mp = getmapping(dp, offset, whence);
- break;
- case SEEK_END:
- if (!dp->maptable)
- return (sfsk(iop, offset, SEEK_END, disc));
- mp = &dummy;
- mp->physical = dp->plast;
- mp->logical = dp->llast;
- break;
- }
- if (sfsetbuf(iop, (char *) iop, 0))
- size = sfslen();
- else
- size = iop->endb - iop->data;
- if (mp) {
- sfsk(iop, mp->physical, SEEK_SET, disc);
- dp->phere = mp->physical;
- dp->lhere = mp->logical;
- if ((*disc->readf) (iop, iop->data, size, disc) < 0)
- return (-1);
- }
- while (1) {
- if (whence == SEEK_CUR && dp->phere >= offset)
- break;
- if (whence == SEEK_SET && dp->lhere >= offset)
- break;
- n = (*disc->readf) (iop, iop->data, size, disc);
- if (n < 0)
- return (-1);
- if (n == 0) {
- if (whence == SEEK_END && offset < 0) {
- offset = dp->lhere;
- whence = SEEK_SET;
- goto retry;
- }
- break;
- }
- }
- if (whence == SEEK_END)
- offset += dp->lhere;
- else {
- physical = cur_offset(dp, offset, iop, whence);
- if (whence == SEEK_SET) {
- sfsk(iop, physical, SEEK_SET, disc);
- dp->phere = physical;
- dp->lhere = offset;
- } else
- offset = physical;
- }
- return (offset);
-}
-
-static int dos_except(Sfio_t * iop, int type, void *arg, Sfdisc_t * disc)
-{
- Dosdisc_t *dp = (Dosdisc_t *) disc;
- if (type == SF_DPOP || type == SF_FINAL) {
- if (dp->bsize > 0)
- free((void *) dp->buff);
- if (dp->mapsize)
- free((void *) dp->maptable);
- free((void *) disc);
- }
- return (0);
-}
-
-int sfdcdos(Sfio_t * f)
-{
- Dosdisc_t *dos;
-
- /* this is a readonly discipline */
- if (sfset(f, 0, 0) & SF_WRITE)
- return (-1);
-
- if (!(dos = (Dosdisc_t *) malloc(sizeof(Dosdisc_t))))
- return -1;
- memset(dos, '\0', sizeof(Dosdisc_t));
-
- dos->disc.readf = dos_read;
- dos->disc.writef = NIL(Sfwrite_f);
- dos->disc.seekf = dos_seek;
- dos->disc.exceptf = dos_except;
-
- if (sfdisc(f, (Sfdisc_t *) dos) != (Sfdisc_t *) dos) {
- free(dos);
- return -1;
- }
-
- return (0);
-}
+++ /dev/null
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/*************************************************************************
- * Copyright (c) 2011 AT&T Intellectual Property
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: See CVS logs. Details at http://www.graphviz.org/
- *************************************************************************/
-
-#include <sfio/sfdchdr.h>
-
-/* Discipline to invoke UNIX processes as data filters.
-** These processes must be able to fit in pipelines.
-**
-** Written by Kiem-Phong Vo, kpv@research.att.com, 03/18/1998.
-*/
-
-#if !defined(FNDELAY) && defined(O_NDELAY)
-#define FNDELAY O_NDELAY
-#endif
-
-typedef struct _filter_s {
- Sfdisc_t disc; /* discipline structure */
- Sfio_t *filter; /* the filter stream */
- char raw[1024]; /* raw data buffer */
- char *next; /* remainder of data unwritten to pipe */
- char *endb; /* end of data */
-} Filter_t;
-
-/* read data from the filter */
-/**
- * @param f stream reading from
- * @param buf buffer to read into
- * @param n number of bytes requested
- * @param disc discipline
- */
-static ssize_t filterread(Sfio_t * f, void * buf, size_t n,
- Sfdisc_t * disc)
-{
- Filter_t *fi;
- ssize_t r, w;
-
- fi = (Filter_t *) disc;
- for (;;) {
- if (!fi->next)
- fi->next = fi->endb = fi->raw;
- else { /* try to get data from filter, if any */
- errno = 0;
- if ((r = sfread(fi->filter, buf, n)) > 0)
- return r;
- if (errno != EWOULDBLOCK)
- return 0;
- }
-
- /* get some raw data to stuff down the pipe */
- if (fi->next >= fi->endb) {
- if ((r = sfrd(f, fi->raw, sizeof(fi->raw), disc)) > 0) {
- fi->next = fi->raw;
- fi->endb = fi->raw + r;
- } else { /* eof, close write end of pipes */
- sfset(fi->filter, SF_READ, 0);
- close(sffileno(fi->filter));
- sfset(fi->filter, SF_READ, 1);
- }
- }
-
- if ((w = fi->endb - fi->next) > 0) {
- errno = 0;
- if ((w = sfwrite(fi->filter, fi->next, w)) > 0)
- fi->next += w;
- else if (errno != EWOULDBLOCK)
- return 0;
- /* pipe is full, sleep for a while, then continue */
- else
- sleep(1);
- }
- }
-}
-
-/**
- * @param f stream reading from
- * @param buf buffer to read into
- * @param n number of bytes requested
- * @param disc discipline
- */
-static ssize_t filterwrite(Sfio_t * f, const void * buf, size_t n,
- Sfdisc_t * disc)
-{
- return -1;
-}
-
-/* for the duration of this discipline, the stream is unseekable */
-static Sfoff_t filterseek(Sfio_t * f, Sfoff_t addr, int offset,
- Sfdisc_t * disc)
-{
- f = NIL(Sfio_t *);
- addr = 0;
- offset = 0;
- disc = NIL(Sfdisc_t *);
- return (Sfoff_t) (-1);
-}
-
-/* on close, remove the discipline */
-static int filterexcept(Sfio_t * f, int type, void * data,
- Sfdisc_t * disc)
-{
- if (type == SF_FINAL || type == SF_DPOP) {
- sfclose(((Filter_t *) disc)->filter);
- free(disc);
- }
-
- return 0;
-}
-
-/**
- * @param f stream to filter data
- * @param cmd program to run as a filter
- */
-int sfdcfilter(Sfio_t * f, const char *cmd)
-{
- Filter_t *fi;
- Sfio_t *filter;
-
- /* open filter for read&write */
- if (!(filter = sfpopen(NIL(Sfio_t *), cmd, "r+")))
- return -1;
-
- /* unbuffered so that write data will get to the pipe right away */
- sfsetbuf(filter, NIL(void *), 0);
-
- /* make the write descriptor nonblocking */
- sfset(filter, SF_READ, 0);
- fcntl(sffileno(filter), F_SETFL, FNDELAY);
- sfset(filter, SF_READ, 1);
-
- /* same for the read descriptor */
- sfset(filter, SF_WRITE, 0);
- fcntl(sffileno(filter), F_SETFL, FNDELAY);
- sfset(filter, SF_WRITE, 1);
-
- if (!(fi = (Filter_t *) malloc(sizeof(Filter_t)))) {
- sfclose(filter);
- return -1;
- }
-
- fi->disc.readf = filterread;
- fi->disc.writef = filterwrite;
- fi->disc.seekf = filterseek;
- fi->disc.exceptf = filterexcept;
- fi->filter = filter;
- fi->next = fi->endb = NIL(char *);
-
- if (sfdisc(f, (Sfdisc_t *) fi) != (Sfdisc_t *) fi) {
- sfclose(filter);
- free(fi);
- return -1;
- }
-
- return 0;
-}
+++ /dev/null
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/*************************************************************************
- * Copyright (c) 2011 AT&T Intellectual Property
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: See CVS logs. Details at http://www.graphviz.org/
- *************************************************************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "sfhdr.h"
-#include <sfdisc.h>
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/*************************************************************************
- * Copyright (c) 2011 AT&T Intellectual Property
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: See CVS logs. Details at http://www.graphviz.org/
- *************************************************************************/
-
-#include <sfio/sfdchdr.h>
-
-
-/*
- * compress.c - File compression ala IEEE Computer, June 1984.
- *
- * Authors: Spencer W. Thomas (decvax!utah-cs!thomas)
- * Jim McKie (decvax!mcvax!jim)
- * Steve Davies (decvax!vax135!petsd!peora!srd)
- * Ken Turkowski (decvax!decwrl!turtlevax!ken)
- * James A. Woods (decvax!ihnp4!ames!jaw)
- * Joe Orost (decvax!vax135!petsd!joe)
- *
- * July, 1992, Jim Arnold
- * Modified uncompress code to work as a discipline under sfio.
- * Didn't need compression code and deleted it.
- *
- * Kiem-Phong Vo (03/18/1998)
- * Small interface modifications to conform with other disciplines.
- */
-
-/*****************************************************************
- * Algorithm from "A Technique for High Performance Data Compression",
- * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.
- *
- * Algorithm:
- * Modified Lempel-Ziv method (LZW). Basically finds common
- * substrings and replaces them with a variable size code. This is
- * deterministic, and can be done on the fly. Thus, the decompression
- * procedure needs no input table, but tracks the way the table was built.
- */
-
-
-#ifndef LZWBITS
-# define LZWBITS 16
-#endif
-#define INIT_BITS 9 /* initial number of bits/code */
-
-
-/* Defines for third byte of header.
- * Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is
- * a fourth header byte (for expansion). If the BLOCK_MASK is set,
- * the CODE_CLEAR is disabled. Instead of flushing all the codes,
- * they are simply overwritten.
- */
-
-#define BIT_MASK 0x1f
-#define BLOCK_MASK 0x80
-
-
-/* The next two codes should not be changed lightly, as they must not
- * lie within the contiguous general code space.
- */
-
-#define CODE_FIRST 257 /* first free entry */
-#define CODE_CLEAR 256 /* table clear output code */
-#define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
-
-
-/* A code_int must hold 2**LZWBITS non-negative values, and also -1
- */
-
-#if LZWBITS > 15
-typedef long int code_int;
-#else
-typedef int code_int;
-#endif
-typedef unsigned char char_type;
-
-
-typedef struct {
- Sfdisc_t disc;
- int init;
- int n_bits; /* number of bits/code */
- int maxbits; /* user settable max # bits/code */
- int block_compress;
- code_int maxcode; /* maximum code, given n_bits */
- code_int maxmaxcode; /* should NEVER generate this code */
- code_int free_ent; /* first unused entry */
- int clear_flg;
- int finchar;
- char_type *stackp;
- code_int code;
- code_int oldcode;
- code_int incode;
- int gc_offset; /* getcode() */
- int gc_size; /* getcode() */
- char_type *gc_buf; /* getcode() */
- char_type *io_ptr;
- char_type *io_end;
- char io_buf[LZWBITS + 8192];
- char_type de_stack[8000];
- char_type tab_suffix[1 << LZWBITS];
- unsigned short tab_prefix[1 << LZWBITS];
-} LZW_Disc;
-
-
-static char_type rmask[9] =
- { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
-
-static int peek(Sfio_t * f, char_type ** bufp, int count,
- LZW_Disc * disc)
-{
- int io_sz, j;
-
- if (count <= 0)
- return count;
- if (count > LZWBITS)
- return -1;
- if ((io_sz = disc->io_end - disc->io_ptr) < count) {
- memcpy(disc->io_buf + LZWBITS - io_sz, disc->io_ptr, io_sz);
- disc->io_ptr = (char_type *) disc->io_buf + LZWBITS - io_sz;
- j = sfrd(f, disc->io_buf + LZWBITS, sizeof disc->io_buf - LZWBITS,
- (Sfdisc_t *) disc);
- if (j < 0)
- j = 0;
- io_sz += j;
- disc->io_end = disc->io_ptr + io_sz;
- }
- *bufp = disc->io_ptr;
- if (io_sz < count)
- count = io_sz;
- disc->io_ptr += count;
- return count;
-}
-
-
-/*****************************************************************
- * TAG( getcode )
- *
- * Read one code from the standard input. If EOF, return -1.
- * Inputs:
- * stdin
- * Outputs:
- * code or -1 is returned.
- */
-
-static code_int getcode(Sfio_t * f, LZW_Disc * disc)
-{
- code_int code;
- int r_off, bits;
- char_type *bp;
-
- if (disc->clear_flg > 0
- || disc->gc_offset >= disc->gc_size
- || disc->free_ent > disc->maxcode) {
- /*
- * If the next entry will be too big for the current code
- * size, then we must increase the size. This implies reading
- * a new buffer full, too.
- */
- if (disc->free_ent > disc->maxcode) {
- if (++disc->n_bits > disc->maxbits)
- return -1;
- if (disc->n_bits == disc->maxbits)
- disc->maxcode = disc->maxmaxcode;
- else
- disc->maxcode = MAXCODE(disc->n_bits);
- }
- if (disc->clear_flg > 0) {
- disc->maxcode = MAXCODE(disc->n_bits = INIT_BITS);
- disc->clear_flg = 0;
- }
- disc->gc_size = peek(f, &disc->gc_buf, disc->n_bits, disc);
- if (disc->gc_size <= 0)
- return -1; /* end of file */
- disc->gc_offset = 0;
- /* Round size down to integral number of codes */
- disc->gc_size = (disc->gc_size << 3) - (disc->n_bits - 1);
- }
- bp = disc->gc_buf;
- r_off = disc->gc_offset;
- bits = disc->n_bits;
- /*
- * Get to the first byte.
- */
- bp += (r_off >> 3);
- r_off &= 7;
- /* Get first part (low order bits) */
- code = (*bp++ >> r_off);
- bits -= (8 - r_off);
- r_off = 8 - r_off; /* now, offset into code word */
- /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
- if (bits >= 8) {
- code |= *bp++ << r_off;
- r_off += 8;
- bits -= 8;
- }
- /* high order bits. */
- code |= (*bp & rmask[bits]) << r_off;
- disc->gc_offset += disc->n_bits;
- return code;
-}
-
-
-static int lzwExcept(Sfio_t * f, int type, void * data, Sfdisc_t * disc)
-{
- if (type == SF_FINAL || type == SF_DPOP)
- free(disc);
- return 0;
-}
-
-
-/*
- * Uncompress. This routine adapts to the codes in the
- * file building the "string" table on-the-fly; requiring no table to
- * be stored in the compressed file. The tables used herein are shared
- * with those of the compress() routine. See the definitions above.
- */
-
-ssize_t lzwRead(Sfio_t * f, void * iobuf, size_t iocnt,
- Sfdisc_t * sfdisc)
-{
- LZW_Disc *disc = (LZW_Disc *) sfdisc;
- char_type *stackp;
- code_int code;
- char *ioend = (char *) iobuf + iocnt;
- char *ioptr = iobuf;
-#define END_REGS {disc->code=code;disc->stackp=stackp;}
-#define BEGIN_REGS {code=disc->code;stackp=disc->stackp;}
-
- BEGIN_REGS if (disc->init <= 0) {
- char_type *p;
-
- if (disc->init < 0)
- return disc->init;
- if (iocnt <= 0)
- return iocnt;
- /* Check the magic number */
- if (peek(f, &p, 3, disc) != 3
- || *p++ != (char_type) 0x1f || *p++ != (char_type) 0x9d)
- return disc->init = -1;
- disc->maxbits = *p; /* set -b from file */
- disc->block_compress = disc->maxbits & BLOCK_MASK;
- disc->maxbits &= BIT_MASK;
- disc->maxmaxcode = 1 << disc->maxbits;
- if (disc->maxbits > LZWBITS)
- return disc->init = -1;
- disc->init = 1;
-
- /*
- * As above, initialize the first 256 entries in the table.
- */
- disc->maxcode = MAXCODE(disc->n_bits = INIT_BITS);
- for (code = 255; code >= 0; code--) {
- disc->tab_prefix[code] = 0;
- disc->tab_suffix[code] = (char_type) code;
- }
- disc->free_ent = ((disc->block_compress) ? CODE_FIRST : 256);
-
- stackp = disc->de_stack;
- disc->finchar = disc->oldcode = getcode(f, disc);
- if (disc->oldcode == -1) { /* EOF already? */
- END_REGS return 0; /* Get out of here */
- }
- *ioptr++ = (char) disc->finchar;
- if ((code = getcode(f, disc)) < 0) {
- END_REGS return 1;
- }
- }
-
- do {
- if (stackp <= disc->de_stack) {
- if ((code == CODE_CLEAR) && disc->block_compress) {
- for (code = 255; code >= 0; code--)
- disc->tab_prefix[code] = 0;
- disc->clear_flg = 1;
- disc->free_ent = CODE_FIRST - 1;
- if ((code = getcode(f, disc)) == -1)
- break;
- } else if (code < 0)
- break;
- disc->incode = code;
- /*
- * Special case for KwKwK string.
- */
- if (code >= disc->free_ent) {
- *stackp++ = disc->finchar;
- code = disc->oldcode;
- }
-
- /*
- * Generate output characters in reverse order
- */
- while (code >= 256) {
- *stackp++ = disc->tab_suffix[code];
- code = disc->tab_prefix[code];
- }
- *stackp++ = disc->finchar = disc->tab_suffix[code];
- }
-
- /*
- * And put them out in forward order
- */
- do {
- if (ioptr >= ioend) {
- END_REGS return iocnt;
- }
- *ioptr++ = *--stackp;
- } while (stackp > disc->de_stack);
-
- /*
- * Generate the new entry.
- */
- if ((code = disc->free_ent) < disc->maxmaxcode) {
- disc->tab_prefix[code] = (unsigned short) disc->oldcode;
- disc->tab_suffix[code] = disc->finchar;
- disc->free_ent = code + 1;
- }
- /*
- * Remember previous code.
- */
- disc->oldcode = disc->incode;
- } while ((code = getcode(f, disc)) >= 0);
- END_REGS return ioptr - (char *) iobuf;
-}
-
-static Sfoff_t lzwSeek(Sfio_t * f, Sfoff_t offset, int whence,
- Sfdisc_t * disc)
-{
- return (Sfoff_t) (-1);
-}
-
-
-static ssize_t lzwWrite(Sfio_t * f, const void * buf, size_t count,
- Sfdisc_t * disc)
-{
- return (ssize_t) (-1);
-}
-
-
-int sfdclzw(Sfio_t * f)
-{
- LZW_Disc *lz;
-
- if (!(lz = (LZW_Disc *) malloc(sizeof(LZW_Disc))))
- return -1;
- lz->disc.readf = lzwRead;
- lz->disc.writef = lzwWrite;
- lz->disc.seekf = lzwSeek;
- lz->disc.exceptf = lzwExcept;
- lz->init = 0;
- lz->clear_flg = 0;
- lz->gc_offset = 0;
- lz->gc_size = 0;
- lz->io_ptr = (char_type *) lz->io_buf + LZWBITS;
- lz->io_end = (char_type *) lz->io_buf + LZWBITS;
-
- if (sfdisc(f, (Sfdisc_t *) lz) != (Sfdisc_t *) lz) {
- free(lz);
- return -1;
- }
-
- return 0;
-}
+++ /dev/null
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/*************************************************************************
- * Copyright (c) 2011 AT&T Intellectual Property
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: See CVS logs. Details at http://www.graphviz.org/
- *************************************************************************/
-
-#include <sfio/sfdchdr.h>
-
-
-/* Discipline to treat a contiguous segment of a stream as a stream
-** in its own right. The hard part in all this is to allow multiple
-** segments of the stream to be used as substreams at the same time.
-**
-** Written by David G. Korn and Kiem-Phong Vo (03/18/1998)
-*/
-
-typedef struct _subfile_s {
- Sfdisc_t disc; /* sfio discipline */
- Sfio_t *parent; /* parent stream */
- Sfoff_t offset; /* starting offset */
- Sfoff_t extent; /* size wanted */
- Sfoff_t here; /* current seek location */
-} Subfile_t;
-
-static ssize_t streamio(Sfio_t * f, void * buf, size_t n,
- Sfdisc_t * disc, int type)
-{
- Subfile_t *su;
- Sfoff_t here, parent;
- ssize_t io;
-
- su = (Subfile_t *) disc;
-
- /* read just what we need */
- if (su->extent >= 0
- && (ssize_t) n > (io = (ssize_t) (su->extent - su->here)))
- n = io;
- if (n <= 0)
- return n;
-
- /* save current location in parent stream */
- parent = sfseek(su->parent, (Sfoff_t) 0, 1);
-
- /* read data */
- here = su->here + su->offset;
- if (sfseek(su->parent, here, 0) != here)
- io = 0;
- else {
- if (type == SF_WRITE)
- io = sfwrite(su->parent, buf, n);
- else
- io = sfread(su->parent, buf, n);
- if (io > 0)
- su->here += io;
- }
-
- /* restore parent current position */
- sfseek(su->parent, parent, 0);
-
- return io;
-}
-
-static ssize_t streamwrite(Sfio_t * f, const void * buf, size_t n,
- Sfdisc_t * disc)
-{
- return streamio(f, (void *) buf, n, disc, SF_WRITE);
-}
-
-static ssize_t streamread(Sfio_t * f, void * buf, size_t n,
- Sfdisc_t * disc)
-{
- return streamio(f, buf, n, disc, SF_READ);
-}
-
-static Sfoff_t streamseek(Sfio_t * f, Sfoff_t pos, int type,
- Sfdisc_t * disc)
-{
- Subfile_t *su;
- Sfoff_t here, parent;
-
- su = (Subfile_t *) disc;
-
- switch (type) {
- case 0:
- here = 0;
- break;
- case 1:
- here = su->here;
- break;
- case 2:
- if (su->extent >= 0)
- here = su->extent;
- else {
- parent = sfseek(su->parent, (Sfoff_t) 0, 1);
- if ((here = sfseek(su->parent, (Sfoff_t) 0, 2)) < 0)
- return -1;
- else
- here -= su->offset;
- sfseek(su->parent, parent, 0);
- }
- break;
- default:
- return -1;
- }
-
- pos += here;
- if (pos < 0 || (su->extent >= 0 && pos >= su->extent))
- return -1;
-
- return (su->here = pos);
-}
-
-static int streamexcept(Sfio_t * f, int type, void * data,
- Sfdisc_t * disc)
-{
- if (type == SF_FINAL || type == SF_DPOP)
- free(disc);
- return 0;
-}
-
-/**
- * @param f stream
- * @param parent parent stream
- * @param offset offset in parent stream
- * @param extent desired size
- */
-int sfdcsubstream(Sfio_t * f, Sfio_t * parent, Sfoff_t offset,
- Sfoff_t extent)
-{
- Subfile_t *su;
- Sfoff_t here;
-
- /* establish that we can seek to offset */
- if ((here = sfseek(parent, (Sfoff_t) 0, 1)) < 0
- || sfseek(parent, offset, 0) < 0)
- return -1;
- else
- sfseek(parent, here, 0);
-
- if (!(su = (Subfile_t *) malloc(sizeof(Subfile_t))))
- return -1;
-
- su->disc.readf = streamread;
- su->disc.writef = streamwrite;
- su->disc.seekf = streamseek;
- su->disc.exceptf = streamexcept;
- su->parent = parent;
- su->offset = offset;
- su->extent = extent;
-
- if (sfdisc(f, (Sfdisc_t *) su) != (Sfdisc_t *) su) {
- free(su);
- return -1;
- }
-
- return 0;
-}
+++ /dev/null
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/*************************************************************************
- * Copyright (c) 2011 AT&T Intellectual Property
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: See CVS logs. Details at http://www.graphviz.org/
- *************************************************************************/
-
-#include <sfio/sfdchdr.h>
-
-/* A discipline to tee the output to a stream to another stream.
-** This is similar to what the "tee" program does. As implemented
-** this discipline only works with file streams.
-**
-** Written by Kiem-Phong Vo, kpv@research.att.com, 03/18/1998.
-*/
-
-/* the discipline structure for tee-ing */
-typedef struct _tee_s {
- Sfdisc_t disc; /* the sfio discipline structure */
- Sfio_t *tee; /* the stream to tee to */
- int status; /* if tee stream is still ok */
-} Tee_t;
-
-/* write to the teed stream. */
-/**
- * @param f the stream being written to
- * @param buf the buffer of data being output
- * @param size the data size
- * @param disc the tee discipline
- */
-static ssize_t teewrite(Sfio_t * f, const void * buf, size_t size,
- Sfdisc_t * disc)
-{
- Tee_t *te = (Tee_t *) disc;
-
- /* tee data if still ok */
- if (te->status == 0 && sfwrite(te->tee, buf, size) != (ssize_t) size)
- te->status = -1;
-
- /* do the actual write */
- return sfwr(f, buf, size, disc);
-}
-
-/* on close, remove the discipline */
-static int teeexcept(Sfio_t * f, int type, void * data, Sfdisc_t * disc)
-{
- if (type == SF_FINAL || type == SF_DPOP)
- free(disc);
-
- return 0;
-}
-
-/**
- * @param f stream to tee from
- * @param tee stream to tee to
- */
-int sfdctee(Sfio_t * f, Sfio_t * tee)
-{
- Tee_t *te;
-
- if (!(te = (Tee_t *) malloc(sizeof(Tee_t))))
- return -1;
-
- te->disc.readf = NIL(Sfread_f);
- te->disc.seekf = NIL(Sfseek_f);
- te->disc.writef = teewrite;
- te->disc.exceptf = teeexcept;
- te->tee = tee;
- te->status = 0;
-
- if (sfdisc(f, (Sfdisc_t *) te) != (Sfdisc_t *) te) {
- free(te);
- return -1;
- }
-
- return 0;
-}
+++ /dev/null
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/*************************************************************************
- * Copyright (c) 2011 AT&T Intellectual Property
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: See CVS logs. Details at http://www.graphviz.org/
- *************************************************************************/
-
-#include <sfio/sfdchdr.h>
-
-
-/* Make a sequence of streams act like a single stream.
-** This is for reading only.
-**
-** Written by Kiem-Phong Vo, kpv@research.att.com, 03/18/1998.
-*/
-
-#define UNSEEKABLE 1
-
-typedef struct _file_s {
- Sfio_t *f; /* the stream */
- Sfoff_t lower; /* its lowest end */
-} File_t;
-
-typedef struct _union_s {
- Sfdisc_t disc; /* discipline structure */
- short type; /* type of streams */
- short c; /* current stream */
- short n; /* number of streams */
- Sfoff_t here; /* current location */
- File_t f[1]; /* array of streams */
-} Union_t;
-
-/**
- * @param f stream involved
- * @param buf buffer to read into
- * @param n number of bytes to read
- * @param disc discipline
- */
-static ssize_t unwrite(Sfio_t * f, const void * buf, size_t n,
- Sfdisc_t * disc)
-{
- return -1;
-}
-
-/**
- * @param f stream involved
- * @param buf buffer to read into
- * @param n number of bytes to read
- * @param disc discipline
- */
-static ssize_t unread(Sfio_t * f, void * buf, size_t n, Sfdisc_t * disc)
-{
- Union_t *un;
- ssize_t r, m;
-
- un = (Union_t *) disc;
- m = n;
- f = un->f[un->c].f;
- while (1) {
- if ((r = sfread(f, buf, m)) < 0 || (r == 0 && un->c == un->n - 1))
- break;
-
- m -= r;
- un->here += r;
-
- if (m == 0)
- break;
-
- buf = (char *) buf + r;
- if (sfeof(f) && un->c < un->n - 1)
- f = un->f[un->c += 1].f;
- }
- return n - m;
-}
-
-static Sfoff_t unseek(Sfio_t * f, Sfoff_t addr, int type, Sfdisc_t * disc)
-{
- Union_t *un;
- int i;
- Sfoff_t extent, s;
-
- un = (Union_t *) disc;
- if (un->type & UNSEEKABLE)
- return -1L;
-
- if (type == 2) {
- extent = 0;
- for (i = 0; i < un->n; ++i)
- extent += (sfsize(un->f[i].f) - un->f[i].lower);
- addr += extent;
- } else if (type == 1)
- addr += un->here;
-
- if (addr < 0)
- return -1;
-
- /* find the stream where the addr could be in */
- extent = 0;
- for (i = 0; i < un->n - 1; ++i) {
- s = sfsize(un->f[i].f) - un->f[i].lower;
- if (addr < extent + s)
- break;
- extent += s;
- }
-
- s = (addr - extent) + un->f[i].lower;
- if (sfseek(un->f[i].f, s, 0) != s)
- return -1;
-
- un->c = i;
- un->here = addr;
-
- for (i += 1; i < un->n; ++i)
- sfseek(un->f[i].f, un->f[i].lower, 0);
-
- return addr;
-}
-
-/* on close, remove the discipline */
-static int unexcept(Sfio_t * f, int type, void * data, Sfdisc_t * disc)
-{
- if (type == SF_FINAL || type == SF_DPOP)
- free(disc);
-
- return 0;
-}
-
-int sfdcunion(Sfio_t * f, Sfio_t ** array, int n)
-{
- Union_t *un;
- int i;
-
- if (n <= 0)
- return -1;
-
- if (!
- (un =
- (Union_t *) malloc(sizeof(Union_t) + (n - 1) * sizeof(File_t))))
- return -1;
-
- un->disc.readf = unread;
- un->disc.writef = unwrite;
- un->disc.seekf = unseek;
- un->disc.exceptf = unexcept;
- un->type = 0;
- un->c = 0;
- un->n = n;
- un->here = 0;
-
- for (i = 0; i < n; ++i) {
- un->f[i].f = array[i];
- if (!(un->type & UNSEEKABLE)) {
- un->f[i].lower = sfseek(array[i], (Sfoff_t) 0, 1);
- if (un->f[i].lower < 0)
- un->type |= UNSEEKABLE;
- }
- }
-
- if (sfdisc(f, (Sfdisc_t *) un) != (Sfdisc_t *) un) {
- free(un);
- return -1;
- }
-
- return 0;
-}
+++ /dev/null
-/* $Id$ $Revision$ */
-/* vim:set shiftwidth=4 ts=8: */
-
-/*************************************************************************
- * Copyright (c) 2011 AT&T Intellectual Property
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors: See CVS logs. Details at http://www.graphviz.org/
- *************************************************************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _SFDISC_H
-#define _SFDISC_H 1
-
-#include <sfio.h>
-
-/* functions to create disciplines */
- extern int sfdcdos(Sfio_t *);
- extern int sfdcfilter(Sfio_t *, const char *);
- extern int sfdclzw(Sfio_t *);
- extern int sfdcsubstream(Sfio_t *, Sfio_t *, Sfoff_t, Sfoff_t);
- extern int sfdctee(Sfio_t *, Sfio_t *);
- extern int sfdcunion(Sfio_t *, Sfio_t **, int);
-#endif
-#ifdef __cplusplus
-}
-#endif