summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-06-16 13:50:22 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-06-16 13:50:22 -0300
commit9fe5be3acf340b90fe0c24d36a601adaf6f21c79 (patch)
treeafab102dd8cb6f7c2ad0b403a4006fe75a2ea7fa
parent611680af08b6102bd260068d9c9ad6961029bd5d (diff)
downloadlua-github-9fe5be3acf340b90fe0c24d36a601adaf6f21c79.tar.gz
library for uniform buffered input.
-rw-r--r--zio.c117
-rw-r--r--zio.h47
2 files changed, 164 insertions, 0 deletions
diff --git a/zio.c b/zio.c
new file mode 100644
index 00000000..aa400f7d
--- /dev/null
+++ b/zio.c
@@ -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;
+}
diff --git a/zio.h b/zio.h
new file mode 100644
index 00000000..7f25b0ad
--- /dev/null
+++ b/zio.h
@@ -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