~vdupras/duskos

9d269a11bbd53ee10ada1dacb993fed989fa5922 — Virgil Dupras 2 months ago 7a61957
ar/puff: stream input from StdIn
2 files changed, 19 insertions(+), 32 deletions(-)

M fs/ar/puff.c
M fs/ar/ungz.fs
M fs/ar/puff.c => fs/ar/puff.c +16 -22
@@ 54,9 54,6 @@ struct state {
	unsigned char out[OUTBUFLEN];	/* output buffer */
	unsigned int outptr;        /* current position in output buffer */
	unsigned int outcnt;		/* total bytes written to out so far */
	unsigned char *in;			/* input buffer */
	unsigned int inlen;			/* available input at in */
	unsigned int incnt;			/* bytes read so far */
	int bitbuf;					/* bit buffer */
	int bitcnt;					/* number of bits in bit buffer */
};


@@ 74,6 71,16 @@ static void spit(unsigned char c) {
	}
}

static unsigned char getc() {
	int c;
	c = stdin();
	if (c < 0) {
		fputs("out of input\n", ConsoleOut());
		abort();
	}
	return c;
}

/*
 * Return need bits from the input stream.	This always leaves less than
 * eight bits in the buffer.  bits() works properly for need == 0.


@@ 92,11 99,7 @@ static int bits(int need)
	/* load at least need bits into val */
	val = s.bitbuf;
	while (s.bitcnt < need) {
		if (s.incnt == s.inlen) {
			fputs("out of input\n", ConsoleOut());
			abort();
		}
		val |= (s.in[s.incnt++]) << s.bitcnt; /* load eight bits */
		val |= getc() << s.bitcnt; /* load eight bits */
		s.bitcnt += 8;
	}



@@ 134,19 137,13 @@ static int stored()
	s.bitcnt = 0;

	/* get length and check against its one's complement */
	if (s.incnt + 4 > s.inlen)
		return 2;								/* not enough input */
	len = s.in[s.incnt++];
	len |= s.in[s.incnt++] << 8;
	if (s.in[s.incnt++] != (~len & $ff) ||
		s.in[s.incnt++] != ((~len >> 8) & $ff))
	len = getc();
	len |= getc() << 8;
	if (getc() != (~len & $ff) || getc() != ((~len >> 8) & $ff))
		return -2;								/* didn't match complement! */

	/* copy len bytes from in to out */
	if (s.incnt + len > s.inlen)
		return 2;								/* not enough input */
	while (len--)
		spit(s.in[s.incnt++]);
	while (len--) spit(getc());

	/* done with a valid stored block */
	return 0;


@@ 673,7 670,7 @@ static int dynamic()
 *	 block (if it was a fixed or dynamic block) are undefined and have no
 *	 expected values to check.
 */
int puff(unsigned char *source, unsigned int sourcelen)
int puff()
{
	int last, type;				/* block information */
	int err;					/* return value */


@@ 681,9 678,6 @@ int puff(unsigned char *source, unsigned int sourcelen)

	s.outptr = 0;
	s.outcnt = 0;
	s.in = source;
	s.inlen = sourcelen;
	s.incnt = 0;
	s.bitbuf = 0;
	s.bitcnt = 0;


M fs/ar/ungz.fs => fs/ar/ungz.fs +3 -10
@@ 7,25 7,18 @@ cc<< /ar/puff.c

: _skiptonull begin stdin not until ;

\ Make it work, then make it work well. puff.c as ported is memory oriented.
\ Creating huge buffers for gzip is ugly, but I just want to make it work.
\ Streaming is coming soon...
$1000 const INBUFSZ
create _inbuf INBUFSZ allot

\ Take a gzip file from stdin and spit the deflated version on stdout
: ungz ( -- err )
  stdin $1f = _assert stdin $8b = _assert \ ID1+ID2
  stdin 8 = _assert \ CM
  stdin >r \ V1=FLG
  _inbuf 6 StdIn IO :read \ useless stuff
  here 6 StdIn IO :read \ useless stuff
  V1 $04 and if \ FLG.EXTRA
    stdin stdin 8 lshift or ( xlen )
    _inbuf swap StdIn IO :read \ read extra
    here swap StdIn IO :read \ read extra
  then
  V1 $08 and if \ FLG.NAME
    _skiptonull then
  r> $10 and if \ FLG.COMMENT
    _skiptonull then
  _inbuf StdIn IO :readall
  _inbuf INBUFSZ puff ;
  puff ;