diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-06-16 13:50:22 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-06-16 13:50:22 -0300 |
commit | 9fe5be3acf340b90fe0c24d36a601adaf6f21c79 (patch) | |
tree | afab102dd8cb6f7c2ad0b403a4006fe75a2ea7fa | |
parent | 611680af08b6102bd260068d9c9ad6961029bd5d (diff) | |
download | lua-github-9fe5be3acf340b90fe0c24d36a601adaf6f21c79.tar.gz |
library for uniform buffered input.
-rw-r--r-- | zio.c | 117 | ||||
-rw-r--r-- | zio.h | 47 |
2 files changed, 164 insertions, 0 deletions
@@ -0,0 +1,117 @@ +/* +* zio.c +* a generic input stream interface +* $Id: zio.c,v 1.5 1997/06/13 13:49:16 lhf Exp $ +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "zio.h" + +#ifdef POPEN +FILE *popen(); +int pclose(); +#else +#define popen(x,y) NULL /* that is, popen always fails */ +#define pclose(x) (-1) +#endif + +/* ----------------------------------------------------- memory buffers --- */ + +static int zmfilbuf(ZIO* z) +{ + return EOZ; +} + +static int zmclose(ZIO* z) +{ + return 1; +} + +ZIO* zmopen(ZIO* z, char* b, int size) +{ + if (b==NULL) return NULL; + z->n=size; + z->p= (unsigned char *)b; + z->filbuf=zmfilbuf; + z->close=zmclose; + z->u=NULL; + return z; +} + +/* ------------------------------------------------------------ strings --- */ + +ZIO* zsopen(ZIO* z, char* s) +{ + if (s==NULL) return NULL; + return zmopen(z,s,strlen(s)); +} + +/* -------------------------------------------------------------- FILEs --- */ + +static int zffilbuf(ZIO* z) +{ + int n=fread(z->buffer,1,ZBSIZE,z->u); + if (n==0) return EOZ; + z->n=n-1; + z->p=z->buffer; + return *(z->p++); +} + +static int zfclose(ZIO* z) +{ + if (z->u==stdin) return 0; + return fclose(z->u); +} + +ZIO* zFopen(ZIO* z, FILE* f) +{ + if (f==NULL) return NULL; + z->n=0; + z->p=z->buffer; + z->filbuf=zffilbuf; + z->close=zfclose; + z->u=f; + return z; +} + +ZIO* zfopen(ZIO* z, char* s, char* m) +{ + return zFopen(z,fopen(s,m)); +} + +/* -------------------------------------------------------------- pipes --- */ + +static int zpclose(ZIO* z) +{ + return pclose(z->u); +} + +ZIO* zpopen(ZIO* z, char* s, char* m) +{ + z=zFopen(z,popen(s,m)); + if (z==NULL) return NULL; + z->close=zpclose; + return z; +} + +/* --------------------------------------------------------------- read --- */ +int zread(ZIO *z, void *b, int n) +{ + while (n) { + int m; + if (z->n == 0) { + if (z->filbuf(z) == EOZ) + return n; /* retorna quantos faltaram ler */ + zungetc(z); /* poe o resultado de filbuf no buffer */ + } + m = (n <= z->n) ? n : z->n; /* minimo de n e z->n */ + memcpy(b, z->p, m); + z->n -= m; + z->p += m; + b = (char *)b + m; + n -= m; + } + return 0; +} @@ -0,0 +1,47 @@ +/* +* zio.h +* a generic input stream interface +* $Id: zio.h,v 1.4 1997/06/13 13:49:16 lhf Exp $ +*/ + +#ifndef zio_h +#define zio_h + +#include <stdio.h> + +#define EOZ (-1) /* end of stream */ + +typedef struct zio ZIO; + +int zgetc(ZIO* z); /* get next byte */ +int zungetc(ZIO* z); /* put back last byte read */ +int zread(ZIO* z, void* b, int n); /* read next n bytes */ +int zclose(ZIO* z); /* close stream */ + +ZIO* zFopen(ZIO* z, FILE* f); /* open FILEs */ +ZIO* zfopen(ZIO* z, char* s, char* m); /* file by name */ +ZIO* zpopen(ZIO* z, char* s, char* m); /* pipe */ +ZIO* zsopen(ZIO* z, char* s); /* string */ +ZIO* zmopen(ZIO* z, char* b, int size); /* memory */ + +#define zgetc(z) (--(z)->n>=0 ? ((int)*(z)->p++): (z)->filbuf(z)) +#define zungetc(z) (++(z)->n,--(z)->p) +#define zclose(z) (*(z)->close)(z) + + + +/* --------- Private Part ------------------ */ + +#define ZBSIZE 256 /* buffer size */ + +struct zio { + int n; /* bytes still unread */ + unsigned char* p; /* current position in buffer */ + int (*filbuf)(ZIO* z); + int (*close)(ZIO* z); + void* u; /* additional data */ + unsigned char buffer[ZBSIZE]; /* buffer */ +}; + + +#endif |