ref: 755bb33714d76e352817e16615b80be02354130f
parent: fa0e134dd85d2acaf09edeb0675047aeb954428b
author: JeffBezanson <[email protected]>
date: Sat Aug 16 23:47:32 EDT 2008
basic ios read, write, and stream creation
--- a/llt/Makefile
+++ b/llt/Makefile
@@ -31,7 +31,7 @@
test:
make clean
- make release CFLAGS=-DENABLE_LLT_TEST
+ make debug CFLAGS=-DENABLE_LLT_TEST
gcc $(TESTSRC) $(TARGET) -o $(TESTER) -lm
./$(TESTER)
--- a/llt/cplxprint.c
+++ b/llt/cplxprint.c
@@ -46,7 +46,7 @@
if (!fzi) {
len = sl = strlen(s);
if (dbl_equals(im, -1)) {
- while (len-sl < (size_t)width-2 && len < (space-3))
+ while ((long)(len-sl) < (long)(width-2) && len < (space-3))
s[len++] = ' ';
s[len] = '-';
s[len+1] = 'i';
@@ -53,7 +53,7 @@
s[len+2] = '\0';
}
else if (dbl_equals(im, 1)) {
- while (len-sl < (size_t)width-1 && len < (space-2))
+ while ((long)(len-sl) < (long)(width-1) && len < (space-2))
s[len++] = ' ';
s[len] = 'i';
s[len+1] = '\0';
--- a/llt/ios.c
+++ b/llt/ios.c
@@ -5,6 +5,7 @@
#include <limits.h>
#include <errno.h>
#include <wchar.h>
+#include <stdio.h> // for printf
#ifdef WIN32
#include <malloc.h>
@@ -15,6 +16,8 @@
#include <unistd.h>
#include <sys/time.h>
#include <sys/select.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#endif
#include "dtypes.h"
@@ -223,7 +226,7 @@
/* interface functions, low level */
-size_t ios_read(ios_t *s, char *dest, size_t n, int all)
+static size_t _ios_read(ios_t *s, char *dest, size_t n, int all)
{
size_t tot = 0;
size_t got, avail;
@@ -289,6 +292,16 @@
return tot;
}
+size_t ios_read(ios_t *s, char *dest, size_t n)
+{
+ return _ios_read(s, dest, n, 0);
+}
+
+size_t ios_readall(ios_t *s, char *dest, size_t n)
+{
+ return _ios_read(s, dest, n, 1);
+}
+
size_t ios_write(ios_t *s, char *data, size_t n)
{
if (n == 0) return 0;
@@ -295,6 +308,7 @@
size_t space;
size_t wrote = 0;
+ if (s->state == bst_none) s->state = bst_wr;
if (s->state == bst_wr)
space = s->maxsize - s->bpos;
else
@@ -308,9 +322,21 @@
return wrote;
}
else if (n <= space) {
+ if (s->bm == bm_line) {
+ char *nl;
+ if ((nl=(char*)memrchr(data, '\n', n)) != NULL) {
+ size_t linesz = nl-data+1;
+ s->bm = bm_block;
+ wrote += ios_write(s, data, linesz);
+ ios_flush(s);
+ s->bm = bm_line;
+ n -= linesz;
+ data += linesz;
+ }
+ }
memcpy(s->buf + s->bpos, data, n);
s->bpos += n;
- wrote = n;
+ wrote += n;
}
else {
s->state = bst_wr;
@@ -331,6 +357,13 @@
off_t ios_seek(ios_t *s, off_t pos)
{
s->_eof = 0;
+ if (s->bm == bm_mem) {
+ if ((size_t)pos > s->size)
+ return -1;
+ s->bpos = pos;
+ return s->bpos;
+ }
+ // TODO
}
off_t ios_seek_end(ios_t *s)
@@ -548,21 +581,155 @@
return ios_copy_(to, from, 0, 1);
}
+static void _ios_init(ios_t *s)
+{
+ // put all fields in a sane initial state
+ s->bm = bm_block;
+ s->state = bst_none;
+ s->errcode = 0;
+ s->buf = NULL;
+ s->maxsize = 0;
+ s->size = 0;
+ s->bpos = 0;
+ s->ndirty = 0;
+ s->tally = 0;
+ s->fd = -1;
+ s->byteswap = 0;
+ s->ownbuf = 0;
+ s->ownfd = 0;
+ s->_eof = 0;
+ s->rereadable = 0;
+}
/* stream object initializers. we do no allocation. */
ios_t *ios_file(ios_t *s, char *fname, int create, int rewrite)
{
+ int fd;
+ int flags = O_RDWR;
+ if (create) flags |= O_CREAT;
+ if (rewrite) flags |= O_TRUNC;
+ fd = open(fname, flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH/*644*/);
+ if (fd == -1) {
+ s->fd = -1;
+ return NULL;
+ }
+ s = ios_fd(s, fd, 1);
+ s->ownfd = 1;
+ return s;
}
ios_t *ios_mem(ios_t *s, size_t initsize)
{
+ _ios_init(s);
+ s->bm = bm_mem;
+ _buf_realloc(s, initsize);
+ return s;
}
-ios_t *ios_fd(ios_t *s, long fd)
+ios_t *ios_str(ios_t *s, char *str)
{
+ size_t n = strlen(str);
+ if (ios_mem(s, n+1)==NULL) return NULL;
+ ios_write(s, str, n+1);
+ ios_seek(s, 0);
+ return s;
}
+ios_t *ios_fd(ios_t *s, long fd, int isfile)
+{
+ _ios_init(s);
+ s->fd = fd;
+ if (isfile) s->rereadable = 1;
+ _buf_init(s, bm_block);
+ s->ownfd = 0;
+ return s;
+}
+ios_t *ios_stdin()
+{
+ static ios_t *_ios_stdin = NULL;
+ if (_ios_stdin == NULL) {
+ _ios_stdin = malloc(sizeof(ios_t));
+ ios_fd(_ios_stdin, STDIN_FILENO, 0);
+ }
+ return _ios_stdin;
+}
+
+ios_t *ios_stdout()
+{
+ static ios_t *_ios_stdout = NULL;
+ if (_ios_stdout == NULL) {
+ _ios_stdout = malloc(sizeof(ios_t));
+ ios_fd(_ios_stdout, STDOUT_FILENO, 0);
+ _ios_stdout->bm = bm_line;
+ }
+ return _ios_stdout;
+}
+
+ios_t *ios_stderr()
+{
+ static ios_t *_ios_stderr = NULL;
+ if (_ios_stderr == NULL) {
+ _ios_stderr = malloc(sizeof(ios_t));
+ ios_fd(_ios_stderr, STDERR_FILENO, 0);
+ _ios_stderr->bm = bm_none;
+ }
+ return _ios_stderr;
+}
+
/* higher level interface */
+int ios_putc(int c, ios_t *s)
+{
+ char ch = (char)c;
+
+ return (int)ios_write(s, &ch, 1);
+}
+
+int ios_getc(ios_t *s)
+{
+ if (s->_eof) return IOS_EOF;
+ char ch;
+ size_t n = ios_read(s, &ch, 1);
+ if (n < 1)
+ return IOS_EOF;
+ return (int)ch;
+}
+
+int ios_ungetc(int c, ios_t *s)
+{
+ if (s->state == bst_wr)
+ return IOS_EOF;
+ if (s->bpos > 0) {
+ s->bpos--;
+ s->buf[s->bpos] = (char)c;
+ return c;
+ }
+ if (s->size == s->maxsize) {
+ if (_buf_realloc(s, s->maxsize*2) == NULL)
+ return IOS_EOF;
+ }
+ memmove(s->buf + 1, s->buf, s->size);
+ s->buf[0] = (char)c;
+ s->size++;
+ return c;
+}
+
+int ios_printf(ios_t *s, char *format, ...)
+{
+ char *str;
+ va_list args;
+
+ va_start(args, format);
+ // TODO: avoid copy
+ int c = vasprintf(&str, format, args);
+ va_end(args);
+
+ if (c == -1) return c;
+
+ ios_write(s, str, c);
+
+ free(str);
+ return c;
+}
--- a/llt/ios.h
+++ b/llt/ios.h
@@ -61,7 +61,8 @@
} ios_t;
/* low-level interface functions */
-size_t ios_read(ios_t *s, char *dest, size_t n, int all);
+size_t ios_read(ios_t *s, char *dest, size_t n);
+size_t ios_readall(ios_t *s, char *dest, size_t n);
size_t ios_write(ios_t *s, char *data, size_t n);
off_t ios_seek(ios_t *s, off_t pos); // absolute seek
off_t ios_seek_end(ios_t *s);
@@ -87,8 +88,12 @@
/* stream creation */
ios_t *ios_file(ios_t *s, char *fname, int create, int rewrite);
ios_t *ios_mem(ios_t *s, size_t initsize);
-ios_t *ios_fd(ios_t *s, long fd);
+ios_t *ios_str(ios_t *s, char *str);
+ios_t *ios_fd(ios_t *s, long fd, int isfile);
// todo: ios_socket
+ios_t *ios_stdin();
+ios_t *ios_stdout();
+ios_t *ios_stderr();
/* high-level functions - output */
int ios_putnum(ios_t *s, char *data, uint32_t type);
@@ -112,13 +117,13 @@
/* stdio-style functions */
#define IOS_EOF (-1)
-int ios_putc(ios_t *s, int c);
+int ios_putc(int c, ios_t *s);
//wint_t ios_putwc(ios_t *s, wchar_t wc);
int ios_getc(ios_t *s);
//wint_t ios_getwc(ios_t *s);
-int ios_ungetc(ios_t *s, int c);
+int ios_ungetc(int c, ios_t *s);
//wint_t ios_ungetwc(ios_t *s, wint_t wc);
-#define ios_puts(s, str) ios_write(s, str, strlen(str))
+#define ios_puts(str, s) ios_write(s, str, strlen(str))
/*
With memory streams, mixed reads and writes are equivalent to performing
@@ -164,21 +169,18 @@
design points:
- data-source independence, including memory streams
- - support 64-bit and large files
- - efficient, low-latency buffering
- - unget
- expose buffer to user, allow user-owned buffers
- allow direct I/O, don't always go through buffer
- buffer-internal seeking. makes seeking back 1-2 bytes very fast,
and makes it possible for sockets where it otherwise wouldn't be
- - special support for utf8
- tries to allow switching between reading and writing
+ - support 64-bit and large files
+ - efficient, low-latency buffering
+ - special support for utf8
- type-aware functions with byte-order swapping service
- position counter for meaningful data offsets with sockets
- note:
- the current code needs to be mostly rewritten. the design should be
- as follows:
+ theory of operation:
the buffer is a view of part of a file/stream. you can seek, read, and
write around in it as much as you like, as if it were just a string.
--- a/llt/unittest.c
+++ b/llt/unittest.c
@@ -43,6 +43,8 @@
printf("u8 took %.4f sec (%d)\n\n", clock_now()-t0, j);
*/
+ test_ios();
+
return 0;
}
@@ -110,4 +112,33 @@
prettyreal(-0.0/0);
prettyreal(DBL_EPSILON);
+}
+
+void test_ios()
+{
+ ios_t *out = ios_stdout();
+ ios_t *in = ios_stdin();
+
+ ios_putc('a', out);
+ ios_putc('b', out);
+ ios_putc('\n', out);
+
+ char c[80];
+ size_t i=0;
+ ios_t sts;
+ ios_str(&sts, "Test string.");
+ c[i++] = ios_getc(&sts);
+ c[i++] = ios_getc(&sts);
+ c[i++] = ios_getc(&sts);
+ c[i++] = '\0';
+ printf("got: \"%s\"\n", c);
+
+ ios_t ms;
+ ios_mem(&ms, 10);
+ int j;
+ for(j=0; j < 16; j++)
+ ios_puts("passersby were amazed by the ", &ms);
+ size_t bs;
+ char *bigstr = ios_takebuf(&ms, &bs);
+ printf("got: \"%s\" (size %d)\n", bigstr, bs);
}