commit 9d269a11bbd53ee10ada1dacb993fed989fa5922
parent 7a619571ed1a12ec43fa28372a67b561febada36
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Wed, 30 Nov 2022 18:33:50 -0500
ar/puff: stream input from StdIn
Diffstat:
2 files changed, 19 insertions(+), 32 deletions(-)
diff --git a/fs/ar/puff.c b/fs/ar/puff.c
@@ -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;
diff --git a/fs/ar/ungz.fs b/fs/ar/ungz.fs
@@ -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 ;