ref: 518415febfea39229bf8a23ad2435009a8c88147
parent: 92542d0b78d27c0b4a17e4fffe2ca08ff5d3c63e
author: Jeff Bezanson <jeff.bezanson@gmail.com>
date: Tue Jun 11 14:15:48 EDT 2013
remove more unused stuff
--- a/llt/Makefile
+++ b/llt/Makefile
@@ -2,7 +2,7 @@
SRCS = bitvector.c hashing.c socket.c timefuncs.c ptrhash.c utf8.c ios.c \
dirpath.c htable.c bitvector-ops.c int2str.c dump.c random.c \
- lltinit.c arraylist.c
+ lltinit.c
OBJS = $(SRCS:%.c=%.o)
DOBJS = $(SRCS:%.c=%.do)
TARGET = libllt.a
--- a/llt/Makefile.macosx
+++ b/llt/Makefile.macosx
@@ -2,7 +2,7 @@
SRCS = bitvector.c hashing.c socket.c timefuncs.c ptrhash.c utf8.c ios.c \
dirpath.c htable.c bitvector-ops.c int2str.c dump.c random.c \
- lltinit.c arraylist.c
+ lltinit.c
OBJS = $(SRCS:%.c=%.o)
DOBJS = $(SRCS:%.c=%.do)
TARGET = libllt.a
--- a/llt/arraylist.c
+++ /dev/null
@@ -1,69 +1,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <limits.h>
-
-#include "dtypes.h"
-#include "arraylist.h"
-
-arraylist_t *arraylist_new(arraylist_t *a, size_t size)
-{
- a->len = 0;
- if (size <= AL_N_INLINE) {
- a->items = &a->_space[0];
- a->max = AL_N_INLINE;
- }
- else {
- a->items = (void**)LLT_ALLOC(size*sizeof(void*));
- a->max = size;
- }
- if (a->items == NULL) return NULL;
- return a;
-}
-
-void arraylist_free(arraylist_t *a)
-{
- if (a->items != &a->_space[0])
- LLT_FREE(a->items);
- a->len = 0;
- a->max = AL_N_INLINE;
- a->items = &a->_space[0];
-}
-
-static void al_grow(arraylist_t *a, size_t n)
-{
- if (a->len+n > a->max) {
- if (a->items == &a->_space[0]) {
- void **p = LLT_ALLOC((a->len+n)*sizeof(void*));
- if (p == NULL) return;
- memcpy(p, a->items, a->len*sizeof(void*));
- a->items = p;
- a->max = a->len+n;
- }
- else {
- size_t nm = a->max*2;
- if (nm == 0) nm = 1;
- while (a->len+n > nm) nm*=2;
- void **p = LLT_REALLOC(a->items, nm*sizeof(void*));
- if (p == NULL) return;
- a->items = p;
- a->max = nm;
- }
- }
- a->len += n;
-}
-
-void arraylist_push(arraylist_t *a, void *elt)
-{
- al_grow(a, 1);
- a->items[a->len-1] = elt;
-}
-
-void *arraylist_pop(arraylist_t *a)
-{
- if (a->len == 0) return NULL;
- void *p = a->items[--a->len];
- a->items[a->len] = NULL;
- return p;
-}
--- a/llt/arraylist.h
+++ /dev/null
@@ -1,19 +1,0 @@
-#ifndef __ARRAYLIST_H_
-#define __ARRAYLIST_H_
-
-#define AL_N_INLINE 29
-
-typedef struct {
- size_t len;
- size_t max;
- void **items;
- void *_space[AL_N_INLINE];
-} arraylist_t;
-
-arraylist_t *arraylist_new(arraylist_t *a, size_t size);
-void arraylist_free(arraylist_t *a);
-
-void arraylist_push(arraylist_t *a, void *elt);
-void *arraylist_pop(arraylist_t *a);
-
-#endif
--- a/llt/attic/ios.c.old
+++ /dev/null
@@ -1,396 +1,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <limits.h>
-#include <errno.h>
-
-#ifdef WIN32
-#include <malloc.h>
-#include <io.h>
-#include <fcntl.h>
-#define fileno _fileno
-#else
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/select.h>
-#endif
-
-#include "dtypes.h"
-#include "utils.h"
-#include "utf8.h"
-#include "ios.h"
-#include "socket.h"
-
-/* OS-level primitive wrappers */
-
-// return error code, #bytes read in *nread
-static int _os_read(long fd, void *buf, size_t n, size_t *nread)
-{
- ssize_t r = read((int)fd, buf, n);
- if (r == -1) {
- *nread = 0;
- return errno;
- }
- *nread = (size_t)r;
- return 0;
-}
-
-static int _os_write(long fd, void *buf, size_t n, size_t *nwritten)
-{
- ssize_t r = write((int)fd, buf, n);
- if (r == -1) {
- *nwritten = 0;
- return errno;
- }
- *nread = (size_t)r;
- return 0;
-}
-
-static int _fd_available(long fd)
-{
-#ifndef WIN32
- fd_set set;
- struct timeval tv = {0, 0};
-
- FD_ZERO(&set);
- FD_SET(fd, &set);
- return (select(fd+1, &set, NULL, NULL, &tv)!=0);
-#else
- return 0;
-#endif
-}
-
-
-/* internal utility functions */
-
-static char *_buf_realloc(ios_t *s, size_t sz)
-{
- char *temp;
-
- if (sz <= s->maxsize)
- return s->buf;
-
- if ((s->buf==NULL || s->buf==&s->local[0]) && (sz <= IOS_INLSIZE)) {
- /* TODO: if we want to allow shrinking, see if the buffer shrank
- down to this size, in which case we need to copy. */
- s->buf = &s->local[0];
- s->maxsize = IOS_INLSIZE;
- s->ownbuf = 1;
- return s->buf;
- }
- else if (s->ownbuf && s->buf != &s->local[0]) {
- // if we own the buffer we're free to resize it
- // always allocate 1 bigger in case user wants to add a NUL
- // terminator after taking over the buffer
- temp = realloc(s->buf, sz+1);
- if (temp == NULL)
- return NULL;
- }
- else {
- temp = malloc(sz+1);
- s->ownbuf = 1;
- if (temp == NULL)
- return NULL;
- }
-
- if (s->buf != temp && s->size > 0)
- memcpy(temp, s->buf, s->size);
- s->buf = temp;
- s->maxsize = sz;
- return s->buf;
-}
-
-// write a block of data into the buffer at the current position, resizing
-// if necessary. returns # written.
-static size_t _writebuf_force(ios_t *s, char *data, size_t n)
-{
- size_t amt;
- size_t newsize;
-
- if (n == 0)
- return 0;
-
- if (s->bpos + n > s->size) {
- if (s->bpos + n > s->maxsize) {
- /* TO DO: here you might want to add a mechanism for limiting
- the growth of the stream. */
- newsize = s->maxsize * 2;
- while (s->bpos + n > newsize)
- newsize *= 2;
- if (_buf_realloc(s, newsize) == NULL) {
- /* no more space; write as much as we can */
- amt = s->maxsize - s->bpos;
- if (amt > 0) {
- memcpy(&s->buf[s->bpos], data, amt);
- }
- s->bpos += amt;
- s->size = s->maxsize;
- return amt;
- }
- }
- s->size = s->bpos + n;
- }
- memcpy(&s->buf[s->bpos], data, n);
- s->bpos += n;
-
- return n;
-}
-
-
-/* interface functions, low level */
-
-size_t ios_read(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)
-{
-}
-
-off_t ios_seek_end(ios_t *s)
-{
-}
-
-off_t ios_skip(ios_t *s, off_t offs)
-{
-}
-
-off_t ios_pos(ios_t *s)
-{
- if (s->bm == bm_mem)
- return (off_t)s->bpos;
-
- off_t fdpos = lseek(s->fd, 0, SEEK_CUR);
- if (fdpos == (off_t)-1)
- return fdpos;
-
- if (s->state == iost_wr)
- fdpos += s->bpos;
- else if (s->state == iost_rd)
- fdpos -= (s->size - s->bpos);
- return fdpos;
-}
-
-size_t ios_trunc(ios_t *s, size_t size)
-{
-}
-
-int ios_eof(ios_t *s)
-{
- if (s->bm == bm_mem)
- return (s->bpos >= s->size);
- if (s->fd == -1)
- return 1;
- // todo
-}
-
-static void _discard_partial_buffer(ios_t *s)
-{
- // this function preserves the invariant that data to write
- // begins at the beginning of the buffer, and s->size refers
- // to how much valid file data is stored in the buffer.
-
- // this needs to be called when normal operation is interrupted in
- // the middle of the buffer. "normal operation" is reading or
- // writing to the end of the buffer. this happens e.g. when flushing.
- if (s->bpos && s->size > s->bpos) {
- memmove(s->buf, s->buf + s->bpos, s->size - s->bpos);
- }
- s->size -= s->bpos;
- s->bpos = 0;
-}
-
-int ios_flush(ios_t *s)
-{
- if (ndirty == 0 || s->bm == bm_mem || s->buf == NULL)
- return 0;
- if (s->fd == -1)
- return -1;
-
- int partialb=0;
- if (s->bitpos > 0 && s->ndirty==s->bpos+1) {
- // flushing partial byte
- partialb=1;
- }
-
- size_t nw, ntowrite=s->ndirty;
- int err = _os_write(s->fd, s->buf, ntowrite, &nw);
- // todo: try recovering from some kinds of errors (e.g. retry)
- if (partialb) {
- // skip back 1, since we might have to write this byte again
- // if more bits in it are changed
- if (lseek(s->fd, -1, SEEK_CUR) == (off_t)-1) {
- // uhoh. can't write the "rest" of this byte. move to next
- // byte instead.
- s->bpos++;
- s->bitpos = 0;
- }
- }
-
- _discard_partial_buffer(s);
- s->ndirty = 0;
-
- if (err)
- return err;
- if (nw < ntowrite)
- return -1;
- return 0;
-}
-
-void ios_close(ios_t *s)
-{
- ios_flush(s);
- if (s->fd != -1 && s->ownfd)
- close(s->fd);
- s->fd = -1;
-}
-
-char *ios_takebuf(ios_t *s, size_t *psize)
-{
- char *buf;
-
- ios_flush(s);
-
- if (s->buf == &s->local[0]) {
- buf = malloc(s->size+1);
- if (buf == NULL)
- return NULL;
- if (s->size)
- memcpy(buf, s->buf, s->size);
- buf[s->size] = '\0';
- }
- else {
- buf = s->buf;
- }
-
- *psize = s->size+1; // buffer is actually 1 bigger for terminating NUL
-
- /* empty stream and reinitialize */
- if (s->bm == bm_mem || s->bm == bm_none) {
- s->buf = &s->local[0];
- s->maxsize = IOS_INLSIZE;
- }
- else {
- s->buf = NULL;
- _buf_realloc(s, IOS_BUFSIZE);
- }
- s->size = s->bpos = 0;
- s->bitpos = 0;
-
- return buf;
-}
-
-int ios_setbuf(ios_t *s, char *buf, size_t size, int own)
-{
- ios_flush(s);
- size_t nvalid=0;
-
- nvalid = s->size;
- if (s->size == s->bpos && s->bitpos>0)
- nvalid++;
- if (size < nvalid)
- nvalid = size;
- memcpy(buf, s->buf, nvalid);
- if (s->bpos > nvalid) {
- // truncated
- s->bpos = nvalid;
- s->bitpos = 0;
- }
- s->size = nvalid;
-
- if (s->buf!=NULL && s->ownbuf && s->buf!=&s->local[0])
- free(s->buf);
- s->buf = buf;
- s->maxsize = size;
- s->ownbuf = own;
- return 0;
-}
-
-int ios_bufmode(ios_t *s, bufmode_t mode)
-{
- // no fd; can only do mem-only buffering
- if (s->fd == -1 && mode != bm_mem)
- return -1;
- s->bm = mode;
- return 0;
-}
-
-void ios_bswap(ios_t *s, int bswap)
-{
- s->byteswap = !!bswap;
-}
-
-int ios_copy(ios_t *to, ios_t *from, size_t nbytes, bool_t all)
-{
-}
-
-
-/* stream object initializers. we do no allocation. */
-
-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)
-{
-}
-
-
-/* higher level interface */
-
-int ios_putbit(ios_t *s, int bit)
-{
- byte_t mask = 1<<s->bitpos;
-
- if (_ios_setstate(s, iost_wr))
- return 0;
-
- if (!s->dirty) {
- // haven't written any bits yet
- // if stenciling is turned on, the buffer is already full and
- // we don't need to do anything
- if (s->rereadable && !s->stenciled) {
- // fill buffer if we can
- }
- }
-
- if (bit)
- s->buf[s->bpos] |= mask;
- else
- s->buf[s->bpos] &= ~mask;
- s->dirty = 1;
-
- s->bitpos++;
- if (s->bitpos > 7) {
- s->bitpos = 0;
- s->bpos++;
- s->tally++;
- }
- return 1;
-}
-
-int ios_getbit(ios_t *s, int *pbit)
-{
- byte_t mask = 1<<s->bitpos;
-
- if (_ios_setstate(s, iost_rd))
- return 0;
-
- *pbit = (s->buf[s->bpos] & mask) ? 1 : 0;
- s->bitpos++;
- if (s->bitpos > 7) {
- s->bitpos = 0;
- s->bpos++;
- s->tally++;
- }
- return 1;
-}
--- a/llt/attic/ios.h.old
+++ /dev/null
@@ -1,198 +1,0 @@
-#ifndef __IOS_H_
-#define __IOS_H_
-
-// this flag controls when data actually moves out to the underlying I/O
-// channel. memory streams are a special case of this where the data
-// never moves out.
-typedef enum { bm_none, bm_line, bm_block, bm_mem } bufmode_t;
-
-typedef enum { iost_none, iost_rd, iost_wr } iostate_t;
-
-#define IOS_INLSIZE 54
-#define IOS_BUFSIZE 4095
-
-typedef struct {
- bufmode_t bm;
-
- // the state only indicates where the underlying file position is relative
- // to the buffer. reading: at the end. writing: at the beginning.
- // in general, you can do any operation in any state.
- iostate_t state;
-
- char *buf; // start of buffer
- size_t maxsize; // space allocated to buffer
- size_t size; // length of valid data in buf, >=ndirty
- size_t bpos; // current position in buffer
- size_t ndirty; // # bytes at &buf[0] that need to be written
-
- // this is a public field that keeps a running count of bytes
- // read or written. you can freely use and change it. this is
- // intended for keeping track of relative positions in streams
- // that don't have absolute positions (like sockets).
- size_t tally;
-
- // pointer-size integer to support platforms where it might have
- // to be a pointer
- long fd;
-
- byte_t bitpos;
- //unsigned char bitdirty:1; // bit buffer needs to be written
- unsigned char byteswap:1;
- //unsigned char readonly:1;
- unsigned char ownbuf:1;
- unsigned char ownfd:1;
-
- // this means you can read, seek back, then read the same data
- // again any number of times. usually only true for files and strings.
- unsigned char rereadable:1;
-
- // this enables "stenciled writes". you can alternately write and
- // seek without flushing in between. this performs read-before-write
- // to populate the buffer, so "rereadable" capability is required.
- // this is off by default, except for bit I/O if rereadable is true.
- unsigned char stenciled:1;
-
- // request durable writes (fsync)
- // unsigned char durable:1;
-
- // todo: mutex
- char local[IOS_INLSIZE];
-} ios_t;
-
-/* low-level interface functions */
-size_t ios_read(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);
-off_t ios_skip(ios_t *s, off_t offs); // relative seek
-off_t ios_pos(ios_t *s); // get current position
-size_t ios_trunc(ios_t *s, size_t size);
-int ios_eof(ios_t *s);
-int ios_flush(ios_t *s);
-void ios_close(ios_t *s);
-char *ios_takebuf(ios_t *s, size_t *psize); // release buffer to caller
-// set buffer space to use
-int ios_setbuf(ios_t *s, char *buf, size_t size, int own);
-int ios_bufmode(ios_t *s, bufmode_t mode);
-void ios_bswap(ios_t *s, int bswap);
-int ios_copy(ios_t *to, ios_t *from, size_t nbytes, bool_t all);
-//void ios_lock(ios_t *s);
-//int ios_trylock(ios_t *s);
-//int ios_unlock(ios_t *s);
-
-/* 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);
-// todo: ios_socket
-
-/* high-level functions - output */
-int ios_putnum(ios_t *s, char *data, uint32_t type);
-int ios_putint(ios_t *s, int n);
-int ios_pututf8(ios_t *s, uint32_t wc);
-int ios_putstringz(ios_t *s, char *str, bool_t do_write_nulterm);
-/* single-bit I/O - even works for mixed reads and writes.
- mixing bit-level I/O with normal byte stream I/O has undefined effects and
- will almost certainly destroy your file. */
-int ios_putbit(ios_t *s, int bit);
-int ios_printf(ios_t *s, char *format, ...);
-
-/* high-level stream functions - input */
-int ios_getnum(ios_t *s, char *data, uint32_t type);
-int ios_getutf8(ios_t *s, uint32_t *pwc);
-int ios_ungetutf8(ios_t *s, uint32_t wc);
-int ios_getstringz(ios_t *dest, ios_t *src);
-int ios_getstringn(ios_t *dest, ios_t *src, size_t nchars);
-int ios_readline(ios_t *dest, ios_t *s, char delim);
-int ios_getline(ios_t *s, char **pbuf, size_t *psz);
-int ios_getbit(ios_t *s, int *pbit); // returns # of bits read (0 or 1)
-
-// seek by utf8 sequence increments
-int ios_nextutf8(ios_t *s);
-int ios_prevutf8(ios_t *s);
-
-/* stdio-style functions */
-#define IOS_EOF (-1)
-int ios_putc(ios_t *s, int c);
-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);
-wint_t ios_ungetwc(ios_t *s, wint_t wc);
-#define ios_puts(s, str) ios_write(s, str, strlen(str))
-
-/*
- With memory streams, mixed reads and writes are equivalent to performing
- sequences of *p++, as either an lvalue or rvalue. File streams behave
- similarly, but other streams might not support this. Using unbuffered
- mode makes this more predictable.
-
- Note on "unget" functions:
- There are two kinds of functions here: those that operate on sized
- blocks of bytes and those that operate on logical units like "character"
- or "integer". The "unget" functions only work on logical units. There
- is no "unget n bytes". You can only do an unget after a matching get.
- However, data pushed back by an unget is available to all read operations.
- The reason for this is that unget is defined in terms of its effect on
- the underlying buffer (namely, it rebuffers data as if it had been
- buffered but not read yet). IOS reserves the right to perform large block
- operations directly, bypassing the buffer. In such a case data was
- never buffered, so "rebuffering" has no meaning (i.e. there is no
- correspondence between the buffer and the physical stream).
-
- Single-bit I/O is able to write partial bytes ONLY IF the stream supports
- seeking. Also, line buffering is not well-defined in the context of
- single-bit I/O, so it might not do what you expect.
-
- implementation notes:
- in order to know where we are in a file, we must ensure the buffer
- is only populated from the underlying stream starting with p==buf.
-
- to switch from writing to reading: flush, set p=buf, cnt=0
- to switch from reading to writing: seek backwards cnt bytes, p=buf, cnt=0
-
- when writing: buf starts at curr. physical stream pos, p - buf is how
- many bytes we've written logically. cnt==0
-
- dirty == (bitpos>0 && state==iost_wr), EXCEPT right after switching from
- reading to writing, where we might be in the middle of a byte without
- having changed it.
-
- to write a bit: if !dirty, read up to maxsize-(p-buf) into buffer, then
- seek back by the same amount (undo it). write onto those bits. now set
- the dirty bit. in this state, we can bit-read up to the end of the byte,
- then formally switch to the read state using flush.
-
- 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
- - single-bit I/O
- - tries to allow switching between reading and writing
- - 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:
-
- 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.
-
- we keep track of the part of the buffer that's invalid (written to).
- we remember whether the position of the underlying stream is aligned
- with the end of the buffer (reading mode) or the beginning (writing mode).
-
- based on this info, we might have to seek back before doing a flush.
-
- as optimizations, we do no writing if the buffer isn't "dirty", and we
- do no reading if the data will only be overwritten.
-*/
-
-#endif
--- a/llt/attic/streams.c
+++ /dev/null
@@ -1,1107 +1,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <limits.h>
-
-#ifdef WIN32
-#include <malloc.h>
-#include <io.h>
-#include <fcntl.h>
-#include <errno.h>
-#define fileno _fileno
-#else
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/select.h>
-#endif
-
-#include "dtypes.h"
-#include "utils.h"
-#include "utf8.h"
-#include "streams.h"
-
-unsigned int type_sizes[] = {
- sizeof(int32_t), sizeof(int8_t), sizeof(int16_t),
- sizeof(int32_t), sizeof(float), sizeof(double), sizeof(int64_t), 0,
-
- /* unsigned */
- 0, sizeof(u_int8_t), sizeof(u_int16_t),
- sizeof(u_int32_t), 0, 0, sizeof(u_int64_t), 0,
-
- /* complex */
- 2*sizeof(int32_t), 2*sizeof(int8_t), 2*sizeof(int16_t),
- 2*sizeof(int32_t), 2*sizeof(float), 2*sizeof(double), 2*sizeof(int64_t),0,
-
- /* complex unsigned */
- 0, 2*sizeof(u_int8_t), 2*sizeof(u_int16_t),
- 2*sizeof(u_int32_t), 0, 0, 2*sizeof(u_int64_t), 0
-};
-
-bool_t valid_type(u_int32_t type)
-{
- u_int32_t sz;
-
- /* irrelevant bits set */
- if (type & ~T_TYPEMASK)
- return false;
- sz = type & T_TYPESIZE;
- if (sz > T_INT64)
- return false;
- if (type == T_CPLX|T_BOOL)
- return false;
- /* no unsigned float or complex unsigned */
- if (type & T_UNSIGNED) {
- if ((sz > T_INT && sz != T_INT64) || sz == T_BOOL || type&T_CPLX)
- return false;
- }
- return true;
-}
-
-/* an important function: some stream routines need to call this at
- various points to ensure proper coexistence with bitwise I/O */
-static void stream_bit_flush(stream_t *s)
-{
- if (s->bitpos > 0) {
- stream_write(s, &s->bitbuf, 1);
- s->bitpos = 0;
- }
-}
-
-void stream_flush(stream_t *s)
-{
- stream_bit_flush(s);
- s->funcs->flush(s);
-}
-
-void stream_free(stream_t *s)
-{
- stream_flush(s);
- s->funcs->free_func(s);
-}
-
-int stream_readfd(stream_t *s)
-{
- if (is_filestream(s)) {
- return fileno(s->fptr);
- }
- else if (is_pipestream(s)) {
- return s->rd;
- }
- return -1;
-}
-
-int stream_writefd(stream_t *s)
-{
- if (is_filestream(s)) {
- return fileno(s->fptr);
- }
- else if (is_pipestream(s)) {
- return s->wd;
- }
- return -1;
-}
-
-
-/* file stream */
-
-off_t fs_seek(struct _stream *s, off_t where)
-{
- FILE *f = s->fptr;
-
- stream_bit_flush(s);
-
- if (fseek(f, where, SEEK_SET) == -1)
- return -1;
- s->pos = ftell(f);
- return s->pos;
-}
-
-off_t fs_skip(struct _stream *s, off_t offs)
-{
- FILE *f = s->fptr;
-
- stream_bit_flush(s);
-
- // a successful fseek always resets the end-of-file condition, even if
- // the offset is zero. we change this so that moving by 0 bytes when you're
- // at eof means you stay at eof.
- if (offs == 0)
- return s->pos;
-
- if (fseek(f, offs, SEEK_CUR) == -1)
- return -1;
- s->pos += offs;
- return s->pos;
-}
-
-off_t fs_seek_end(struct _stream *s)
-{
- FILE *f = s->fptr;
-
- stream_bit_flush(s);
-
- if (fseek(f, 0, SEEK_END) == -1)
- return -1;
- s->pos = ftell(f);
- return s->pos;
-}
-
-size_t fs_read(struct _stream *s, char *dest, size_t size)
-{
- FILE *f = s->fptr;
- size_t c;
-
- c = fread(dest, 1, size, f); /* read single-byte entities */
- s->pos += c;
- return c;
-}
-
-size_t fs_write(struct _stream *s, char *data, size_t size)
-{
- FILE *f = s->fptr;
- size_t c;
-
- c = fwrite(data, 1, size, f);
- s->pos += c;
- return c;
-}
-
-size_t fs_trunc(struct _stream *s, size_t size)
-{
- FILE *f = s->fptr;
-
-#ifndef WIN32
- if (ftruncate(fileno(f), s->pos) == -1)
- return -1; // TODO this should be unsigned!
-#else
- if (_chsize(_fileno(f), s->pos) == -1)
- return -1;
-#endif
- return s->pos;
-}
-
-void fs_flush(struct _stream *s)
-{
- FILE *f = s->fptr;
-
- (void)fflush(f);
-}
-
-bool_t fs_eof(struct _stream *s)
-{
- return (bool_t)feof(s->fptr);
-}
-
-void free_fs_stream(stream_t *s)
-{
- fclose(s->fptr);
- free(s->name);
-}
-
-void stream_close(stream_t *s)
-{
- /*
- if (!is_filestream(s))
- return;
- */
- stream_flush(s);
- // so far file streams are not designed to exist in the closed state
- // fclose(s->fptr);
-}
-
-stream_interface_t fs_funcs =
- {free_fs_stream, fs_seek, fs_seek_end, fs_skip,
- fs_read, fs_write, fs_trunc, fs_eof, fs_flush};
-
-stream_t *filestream_new(stream_t *s,
- char *fName, bool_t create, bool_t rewrite)
-{
- FILE *f;
- size_t sz;
-
- if (create) {
- if (rewrite) {
- f = fopen(fName, "w+b");
- }
- else {
- f = fopen(fName, "a+b");
- if (f)
- fseek(f, 0, SEEK_SET);
- }
- }
- else {
- f = fopen(fName, "r+b");
- }
- if (f == NULL) {
- /* try readonly */
- f = fopen(fName, "rb");
- if (f == NULL)
- return NULL;
- }
-
- s->fptr = f;
- s->name = strdup(fName);
-
- s->funcs = &fs_funcs;
-
- s->pos = 0;
- s->bitpos = s->bitbuf = 0;
- s->byteswap = false;
- return s;
-}
-
-stream_t *stream_fromfile(stream_t *s, FILE *f, char *name)
-{
- s->fptr = f;
- s->name = strdup(name);
-
- s->funcs = &fs_funcs;
-
- s->pos = 0;
- s->bitpos = s->bitbuf = 0;
- s->byteswap = false;
- return s;
-}
-
-/* memory stream */
-
-off_t ms_seek(struct _stream *s, off_t where)
-{
- if ((size_t)where > s->size)
- return -1;
-
- stream_bit_flush(s);
- s->pos = where;
-
- return s->pos;
-}
-
-off_t ms_skip(struct _stream *s, off_t offs)
-{
- if (s->pos+offs < 0 || s->pos+offs > s->size)
- return -1;
-
- stream_bit_flush(s);
-
- s->pos += offs;
- return s->pos;
-}
-
-off_t ms_seek_end(struct _stream *s)
-{
- stream_bit_flush(s);
- s->pos = s->size;
- return s->pos;
-}
-
-size_t ms_read(struct _stream *s, char *dest, size_t size)
-{
- size_t amt = size;
-
- assert(s->pos <= s->size);
-
- if (size == 0)
- return 0;
-
- if (s->size - s->pos < size)
- amt = s->size - s->pos;
-
- if (amt > 0) {
- memcpy(dest, &s->data[s->pos], amt);
- }
-
- s->pos += amt;
- return amt;
-}
-
-static char *ms_realloc(stream_t *s, size_t size)
-{
- char *temp;
-
- if (size <= s->maxsize)
- return s->data;
-
- /* UNOFFICIALLY, we put a '\0' at the end of every memory stream for
- compatability with C library string functions, which are convenient.
- You are not allowed to depend on this behavior; it may eventually
- change.
-
- We implement this by telling everybody that maxsize is one less than
- the actual size of the buffer. They think the last byte is at index
- maxsize-1, but it is actually at index maxsize.
-
- data[s->size] and data[s->maxsize] are kept at '\0'. */
-
- if (size <= N_STREAM_LOCAL-1) {
- /* TO DO: if we want to allow shrinking, see if the buffer shrank
- down to this size, in which case we need to copy. */
- s->data = &s->local[0];
- s->maxsize = N_STREAM_LOCAL-1;
- s->data[s->maxsize] = '\0';
- return s->data;
- }
- if (s->data == &s->local[0]) {
- temp = malloc(size+1);
- // TODO nullcheck
- memcpy(temp, s->data, s->size);
- }
- else {
- /* here we rely on the realloc() behavior of
- doing a malloc() when passed a NULL pointer. */
- temp = realloc(s->data, size+1);
- if (temp == NULL)
- return NULL;
- }
- s->data = temp;
- s->maxsize = size;
- s->data[s->maxsize] = '\0';
- return s->data;
-}
-
-size_t ms_trunc(struct _stream *s, size_t size)
-{
- if (size == s->size)
- return size;
-
- if (size < s->size) {
- // TODO: if big shrink, release space
- if (s->pos > size)
- s->pos = size;
- }
- else {
- if (ms_realloc(s, size) == NULL)
- return s->size;
- }
-
- s->size = size;
- s->data[size] = '\0';
- return size;
-}
-
-size_t ms_write(struct _stream *s, char *data, size_t size)
-{
- size_t amt;
- size_t newsize;
-
- if (size == 0)
- return 0;
-
- if (s->pos + size > s->size) {
- if (s->pos + size > s->maxsize) {
- /* TO DO: here you might want to add a mechanism for limiting
- the growth of the stream. */
- newsize = s->maxsize * 2;
- while (s->pos + size > newsize)
- newsize *= 2;
- if (ms_realloc(s, newsize) == NULL) {
- /* no more space; write as much as we can */
- amt = s->maxsize - s->pos;
- if (amt > 0) {
- memcpy(&s->data[s->pos], data, amt);
- }
- s->pos += amt;
- s->size = s->maxsize;
- /* in this case we've written up to the end of the buffer,
- so we know the next char is \0 since ms_realloc sets that
- up every time it allocates. */
- return amt;
- }
- }
- s->size = s->pos + size;
-
- /* always valid since secretly we know the buffer is 1 bigger than
- maxsize */
- s->data[s->size] = '\0';
- }
- memcpy(&s->data[s->pos], data, size);
- s->pos += size;
-
- return size;
-}
-
-void ms_flush(struct _stream *s)
-{
-}
-
-bool_t ms_eof(struct _stream *s)
-{
- assert(s->pos <= s->size);
- return (bool_t)(s->pos == s->size);
-}
-
-void free_ms_stream(stream_t *s)
-{
- if (s->data != NULL && s->data != &s->local[0])
- free(s->data);
-}
-/*
-stream_t *memstream_copy(stream_t *s)
-{
- stream_t *ns = memstream_new(s->size);
-
- ms_write(ns, s->s, s->size);
- stream_seek(ns, 0);
- return ns;
-}
-*/
-stream_interface_t ms_funcs =
- {free_ms_stream, ms_seek, ms_seek_end, ms_skip,
- ms_read, ms_write, ms_trunc, ms_eof, ms_flush};
-
-stream_t *memstream_new(stream_t *s, size_t initsize)
-{
- s->pos = 0;
- s->size = 0;
- s->data = &s->local[0];
- s->maxsize = N_STREAM_LOCAL-1;
- s->data[s->maxsize] = '\0';
-
- if (ms_realloc(s, initsize) == NULL)
- julia_outofmemory();
-
- s->data[initsize] = '\0';
- s->data[s->pos] = '\0';
- s->size = initsize;
-
- s->funcs = &ms_funcs;
-
- s->bitpos = s->bitbuf = 0;
- s->byteswap = false;
-
- return s;
-}
-
-#if 0
-string_t *string_new(int len)
-{
- string_t *str;
-
- str = memstream_new(len);
- str->len = len;
-
- return str;
-}
-
-/* this function makes string streams from C strings (NUL-term) */
-string_t *string_fromc(char *s)
-{
- string_t *str;
- int len = strlen(s);
-
- str = string_new(len);
- stream_write(str, s, len);
- stream_seek(str, 0);
-
- return str;
-}
-#endif
-
-/* pipe */
-off_t ps_seek(struct _stream *s, off_t where)
-{
- return -1;
-}
-
-size_t ps_read(struct _stream *s, char *dest, size_t size);
-
-off_t ps_skip(struct _stream *s, off_t offs)
-{
- char buf[CHUNK_SIZE];
- int rd = s->rd;
- size_t c, amt;
-
- if (offs < 0)
- return -1;
- while (offs > 0) {
- amt = offs > CHUNK_SIZE ? CHUNK_SIZE : offs;
- c = ps_read(s, buf, amt);
- if (c < amt)
- return 0;
- offs -= c;
- }
- return 0;
-}
-
-off_t ps_seek_end(struct _stream *s)
-{
- return -1;
-}
-
-size_t ps_read(struct _stream *s, char *dest, size_t size)
-{
- if (ps_eof(s))
- return 0;
-#ifdef WIN32
- int c = _read(s->rd, dest, size);
-#else
- ssize_t c = read(s->rd, dest, size);
-#endif
- if (c < 0)
- return 0;
- return (size_t)c;
-}
-
-size_t ps_write(struct _stream *s, char *data, size_t size)
-{
-#ifdef WIN32
- int c = _write(s->wd, data, size);
-#else
- ssize_t c = write(s->wd, data, size);
-#endif
- if (c < 0)
- return 0;
- return c;
-}
-
-size_t ps_trunc(struct _stream *s, size_t size)
-{
- return 0;
-}
-
-void ps_flush(struct _stream *s)
-{
-}
-
-bool_t ps_eof(struct _stream *s)
-{
-#ifndef WIN32
- fd_set set;
- struct timeval tv = {0, 0};
-
- FD_ZERO(&set);
- FD_SET(s->rd, &set);
- return (select(s->rd+1, &set, NULL, NULL, &tv)==0);
-#else
- return 0;
-#endif
-}
-
-void free_ps_stream(stream_t *s)
-{
- close(s->rd);
- close(s->wd);
-}
-
-stream_interface_t ps_funcs =
- {free_ps_stream, ps_seek, ps_seek_end, ps_skip,
- ps_read, ps_write, ps_trunc, ps_eof, ps_flush};
-
-stream_t *pipestream_new(stream_t *s, int flags)
-{
- int fds[2];
-
- s->funcs = &ps_funcs;
-
-#ifdef WIN32
- _pipe(&fds[0], 32768, _O_BINARY | flags);
-#else
- pipe(&fds[0]);
-#endif
- s->rd = fds[0]; s->wd = fds[1];
-
- s->byteswap = false;
- s->bitpos = s->bitbuf = 0;
- s->pos = 0;
-
- return s;
-}
-
-
-/* high-level stream functions */
-
-/* type is a "T_" code as defined in streams.h */
-int stream_put_num(stream_t *stream, char *d, u_int32_t type)
-{
- int c, sz, i;
-
- assert(valid_type(type));
- sz = type_sizes[type];
-
- if (!stream->byteswap) {
- c = stream_write(stream, d, sz);
- }
- else if (sz >= 4) {
- char temp[32];
- if (type & T_CPLX) {
- bswap_to(temp, (byte_t*)d, sz/2);
- bswap_to(temp+sz/2, (byte_t*)d+sz/2, sz/2);
- }
- else {
- bswap_to(temp, (byte_t*)d, sz);
- }
- c = stream_write(stream, temp, sz);
- }
- else {
- assert(sz == 2 || sz == 1);
- if (type & T_CPLX) {
- c = stream_write(stream, &d[0], 2);
- /*
- for(i=sz/2-1; i >= 0; i--) {
- c += stream_write(stream, &d[i], 1);
- }
- for(i=sz-1; i >= sz/2; i--) {
- c += stream_write(stream, &d[i], 1);
- }
- */
- }
- else {
- c = 0;
- if (sz == 2)
- c += stream_write(stream, &d[1], 1);
- c += stream_write(stream, &d[0], 1);
- }
- }
-
- return c;
-}
-
-int stream_get_num(stream_t *s, char *data, u_int32_t type)
-{
- int c, sz;
-
- assert(valid_type(type));
- sz = type_sizes[type];
-
- c = stream_read(s, data, sz);
-
- if (s->byteswap && c == sz) {
- if (type & T_CPLX) {
- bswap((byte_t*)data, sz/2);
- bswap((byte_t*)data+sz/2, sz/2);
- }
- else {
- bswap((byte_t*)data, sz);
- }
- }
- if (c < sz)
- return -1;
- return c;
-}
-
-int stream_put_int(stream_t *s, int n)
-{
- return stream_put_num(s, (char*)&n, T_INT);
-}
-
-int stream_put_char(stream_t *s, u_int32_t wc)
-{
- char buf[8];
- int amt;
-
- amt = u8_wc_toutf8(buf, wc);
- return stream_write(s, buf, amt);
-}
-
-int stream_put_stringz(stream_t *s, char *str, bool_t nulterm)
-{
- int c, l = strlen(str);
-
- c = stream_write(s, str, l);
- if (nulterm)
- c += stream_write(s, &str[l], 1);
- return c;
-}
-
-int stream_get_char(stream_t *s, u_int32_t *pwc)
-{
- char buf[8];
- int amt;
- unsigned int i;
-
- amt = stream_read(s, buf, 1);
- if (amt == 0)
- return 0;
- amt = u8_seqlen(buf) - 1; // find out how many more bytes in this seq
- if (amt) {
- stream_read(s, &buf[1], amt);
- }
- amt++;
- buf[amt] = '\0';
- i=0;
- *pwc = u8_nextmemchar(buf, &i);
- return i;
-}
-
-int stream_nextchar(stream_t *s)
-{
- u_int32_t wc;
-
- if (is_memstream(s)) {
- if (stream_eof(s))
- return -1;
- stream_bit_flush(s);
- s->pos++;
- while (!stream_eof(s) && !isutf(s->s[s->pos]))
- s->pos++;
- return s->pos;
- }
-
- if (stream_get_char(s, &wc) == 0)
- return -1;
- return s->pos;
-}
-
-int stream_prevchar(stream_t *s)
-{
- char c;
-
- if (is_memstream(s)) {
- if (s->pos == 0)
- return -1;
- stream_bit_flush(s);
- s->pos--;
- while (s->pos > 0 && !isutf(s->s[s->pos]))
- s->pos--;
- return s->pos;
- }
-
- do {
- if (stream_skip(s, -1) == -1)
- return -1;
- stream_read(s, &c, 1);
- stream_skip(s, -1);
- } while(!isutf(c));
- return s->pos;
-}
-
-void stream_put_bit(stream_t *s, int bit)
-{
- byte_t mask = 0x1;
-
- if (s->bitpos == 0) {
- if (!stream_read(s, &s->bitbuf, 1)) {
- s->bitbuf = 0;
- }
- else {
- stream_skip(s, -1);
- }
- }
-
- mask <<= s->bitpos;
- if (bit)
- s->bitbuf |= mask;
- else
- s->bitbuf &= ~mask;
- s->dirty = 1;
-
- s->bitpos++;
- if (s->bitpos > 7) {
- s->bitpos = 0;
- stream_write(s, &s->bitbuf, 1);
- }
-}
-
-int stream_get_bit(stream_t *s, int *pbit)
-{
- byte_t mask = 0x1;
-
- if (s->bitpos == 0) {
- if (!stream_read(s, &s->bitbuf, 1)) {
- return 0;
- }
- else {
- stream_skip(s, -1);
- }
- s->dirty = 0;
- }
-
- mask <<= s->bitpos;
- *pbit = (s->bitbuf & mask) ? 1 : 0;
-
- s->bitpos++;
-
- if (s->bitpos > 7) {
- s->bitpos = 0;
- if (s->dirty) {
- stream_write(s, &s->bitbuf, 1);
- }
- else {
- stream_skip(s, 1);
- }
- }
- return 1;
-}
-
-/* warning: DO NOT write a trivial wrapper for this function; it allows
- easily crashing the interpreter using unfriendly format strings.
-
- also, this function is designed to print small things like messages. it
- cannot print arbitrarily large data. to do that, use stream_write,
- or repeated calls to this function.
-
- TODO: this doesn't handle UTF-8 properly:
-
-printf("%*s|\n%*s|\n", -4, "X", -4, "a")
-printf("%-4s|\n%-4s|\n", "X", "a")
-X |
-a |
-
-Where X is a 2-byte character.
-*/
-int stream_printf(stream_t *s, char *format, ...)
-{
- int c;
- va_list args;
- char buf[512];
-
- va_start(args, format);
- c = vsnprintf(buf, sizeof(buf), format, args);
- va_end(args);
-
- if (c < 0)
- return 0;
-
- if ((unsigned)c > sizeof(buf))
- c = sizeof(buf);
-
- return stream_write(s, buf, c);
-}
-
-char *stream_take_buffer(stream_t *s, size_t *size)
-{
- char *buf;
-
- if (!is_memstream(s) || s->data == NULL)
- return NULL;
-
- stream_flush(s);
-
- if (s->data == &s->local[0]) {
- buf = malloc(s->size+1);
- if (buf == NULL)
- return NULL;
- memcpy(buf, s->data, s->size+1);
- buf[s->size] = '\0';
- }
- else {
- buf = s->data;
- }
-
- *size = s->size+1; /* buffer is actually 1 bigger for terminating NUL */
-
- /* empty stream and reinitialize */
- s->data = &s->local[0];
- s->maxsize = N_STREAM_LOCAL-1;
- s->data[s->maxsize] = '\0';
- stream_trunc(s, 0);
-
- return buf;
-}
-
-/* Chunk size for reading lines: if too small, then we make too many low-level
- calls. if too large, then we waste time reading bytes beyond the end of the
- current line. this is effectively a guess as to how big a line is.
- this value should be < N_STREAM_LOCAL, allowing at least some lines to
- fit without extra allocation. */
-#define LINE_CHUNK_SIZE (N_STREAM_LOCAL-1)
-
-int stream_readline(stream_t *dest, stream_t *s, char delim)
-{
- char chunk[LINE_CHUNK_SIZE];
- int i, cnt, total=0;
-
- if (stream_eof(s))
- return 0;
-
- do {
- cnt = stream_read(s, chunk, LINE_CHUNK_SIZE);
- for(i=0; i < cnt; i++) {
- if (chunk[i] == delim)
- break;
- }
- if (i < cnt) {
- total += stream_write(dest, chunk, i+1);
- stream_skip(s, -(cnt-(i+1)));
- break;
- }
- total += stream_write(dest, chunk, cnt);
- } while (!stream_eof(s));
-
- return total;
-}
-
-/* extract one line of text from a stream, into a memory buffer.
- a pointer to the buffer is returned in *pbuf, the size of the buffer
- in *psz, and the number of characters in the line (including newline) is
- returned. the line may contain NULs, but there will also be a NUL
- terminator as the last character in the buffer.
-
- This routine's behavior is not exactly the same as GNU getline. In
- particular, it always allocates a buffer.
-*/
-int stream_getline(stream_t *s, char **pbuf, size_t *psz)
-{
- stream_t buf;
-
- memstream_new(&buf, 0);
-
- stream_readline(&buf, s, '\n');
-
- *pbuf = stream_take_buffer(&buf, psz);
-
- return *psz-1;
-}
-
-int stream_get_stringz(stream_t *dest, stream_t *src)
-{
- return stream_readline(dest, src, '\0');
-}
-
-/* get n UTF-8 characters */
-int stream_get_stringn(stream_t *dest, stream_t *src, size_t c)
-{
- u_int32_t wc;
- size_t cnt=0;
-
- while (c > 0) {
- if (stream_get_char(src, &wc) == 0 ||
- stream_put_char(dest, wc) == 0)
- break;
- c--;
- cnt++;
- }
- return cnt;
-}
-
-/* TODO: change API to allow passing a heap-allocated page-aligned
- chunk to reuse on each copy. if it's NULL we alloc our own. */
-int stream_copy(stream_t *to, stream_t *from, size_t nbytes, bool_t all)
-{
- int c=0, cnt, wc, rdc;
- char buf[CHUNK_SIZE];
- int remain = all ? CHUNK_SIZE : nbytes;
-
- if (is_memstream(to)) {
- // avoid extra copy, read directly into memstream
- while (!stream_eof(from)) {
- if (all) {
- rdc = CHUNK_SIZE;
- }
- else {
- /* if !all, only 1 call to stream_read needed */
- rdc = nbytes;
- }
-
- if (ms_realloc(to, to->pos + rdc) == NULL) {
- rdc = to->maxsize - to->pos;
- if (rdc == 0)
- break;
- }
- cnt = stream_read(from, &to->s[to->pos], rdc);
- wc = cnt;
- to->pos += wc;
- if (to->pos > to->size) {
- to->size = to->pos;
- to->s[to->size] = '\0';
- }
- c += wc;
-
- if (!all)
- remain -= wc;
- if (wc < rdc || remain == 0)
- break;
- }
- }
- else if (is_memstream(from)) {
- while (1) {
- if (all) {
- rdc = CHUNK_SIZE;
- }
- else {
- /* if !all, only 1 call to stream_read needed */
- rdc = nbytes;
- }
- // check for source out of data
- if (from->size - from->pos < rdc) {
- remain = rdc = from->size - from->pos;
- }
- cnt = stream_write(to, &from->s[from->pos], rdc);
- wc = cnt;
- from->pos += wc;
- c += wc;
- if (!all)
- remain -= wc;
- if (wc < rdc || remain == 0)
- break;
- }
- }
- else {
- while (!stream_eof(from)) {
- rdc = remain>CHUNK_SIZE ? CHUNK_SIZE : remain;
-
- cnt = stream_read(from, buf, rdc);
- wc = stream_write(to, buf, cnt);
- c += wc;
-
- if (!all)
- remain -= wc;
- if (wc < rdc || remain == 0)
- break;
- }
- }
- return c;
-}
-
-
-/* serialization functions */
-
-/* nbytes is either 4 or 8 */
-size_t stream_get_offset(stream_t *s, off_t *po, int nbytes)
-{
- size_t c;
- int64_t off64;
- int32_t off32;
-
- if (nbytes == 4) {
- c = stream_read(s, (char*)&off32, nbytes);
- if (c < nbytes)
- return c;
- if (s->byteswap)
- off32 = bswap_32(off32);
- /* OK on either system since off_t is >= off32 in size */
- *po = (off_t)off32;
- }
- else {
- c = stream_read(s, (char*)&off64, nbytes);
- if (c < nbytes)
- return c;
- if (s->byteswap)
- off64 = bswap_64(off64);
- if (sizeof(off_t) == 8) {
- *po = (off_t)off64;
- }
- else {
- if (off64 <= INT_MAX && off64 >= INT_MIN) {
- // downcast safe
- *po = (off_t)off64;
- }
- else {
- cerror("I/O error: 64-bit offset truncated on input.\n");
- }
- }
- }
-
- return c;
-}
-
-size_t stream_put_offset(stream_t *s, off_t o, int nbytes)
-{
- int64_t off64;
- int32_t off32;
-
- if (nbytes == 4) {
- if (sizeof(off_t) == 8 && (o > INT_MAX || o < INT_MIN)) {
- cerror("I/O error: 64-bit offset truncated on output.\n");
- }
- off32 = (int32_t)o;
- if (s->byteswap)
- off32 = bswap_32(off32);
- return stream_write(s, (char*)&off32, 4);
- }
- off64 = (int64_t)o;
- if (s->byteswap)
- off64 = bswap_64(off64);
- return stream_write(s, (char*)&off64, 8);
-}
--- a/llt/attic/streams.h
+++ /dev/null
@@ -1,213 +1,0 @@
-#ifndef __STREAMS_H_
-#define __STREAMS_H_
-
-struct _stream;
-
-// numeric type codes
-#define T_BOOL 0x000
-#define T_BYTE 0x001
-#define T_SHORT 0x002
-#define T_INT 0x003
-#define T_FLOAT 0x004
-#define T_DOUBLE 0x005
-#define T_INT64 0x006
-//#define T_LDOUBLE 0x007
-#define T_UNSIGNED 0x008
-#define T_CPLX 0x010
-
-#define T_TYPEMASK 0x1f /* bits related to numeric type */
-#define T_TYPESIZE 0x07 /* bits related to type size */
-
-#define is_type(a, t) (((a) & T_TYPESIZE) == (t))
-// type_bitseq tells whether 2 types are bit-representation compatible
-#define type_bitseq(a, b) (((a) & ~T_UNSIGNED) == ((b) & ~T_UNSIGNED))
-
-extern unsigned int type_sizes[];
-
-typedef struct {
- void (*free_func)(struct _stream *s);
- /* these return -1 on error, or new position if successful */
- /* set absolute position */
- off_t (*seek)(struct _stream *s, off_t where);
- /* seek to end (past last byte) */
- off_t (*seek_end)(struct _stream *s);
- /* move relative to current position */
- off_t (*skip)(struct _stream *s, off_t offs);
-
- /* these return # of bytes read/written, 0 on error */
- size_t (*read)(struct _stream *s, char *dest, size_t size);
- size_t (*write)(struct _stream *s, char *data, size_t size);
-
- /* truncate a stream to the given length */
- size_t (*trunc)(struct _stream *s, size_t size);
-
- /* no data left? */
- bool_t (*eof)(struct _stream *s);
-
- /* sync bit buffer, and sync to hardware if applicable */
- void (*flush)(struct _stream *s);
- /* could add fsync() call for durable writes */
-} stream_interface_t;
-
-extern stream_interface_t fs_funcs;
-extern stream_interface_t ms_funcs;
-extern stream_interface_t ps_funcs;
-
-#define is_memstream(s) (((stream_t*)s)->funcs==&ms_funcs)
-#define is_filestream(s) (((stream_t*)s)->funcs==&fs_funcs)
-#define is_pipestream(s) (((stream_t*)s)->funcs==&ps_funcs)
-
-/* general i/o chunk size */
-#define CHUNK_SIZE 4096
-
-/* this should be a multiple of 4; otherwise the struct gets padded to
- the next multiple of 4 anyway, wasting space */
-#define N_STREAM_LOCAL 40
-
-typedef struct _stream {
- /* unfortunately, it seems that pos needs to be a signed type to be
- compatible with OS functions. */
- off_t pos;
- byte_t bitpos; /* offset within a byte, for writing individual bits */
- byte_t bitbuf; /* a copy of the byte at the current stream position */
- char ungotc;
- struct {
- /* does bit buffer need to be written? */
- unsigned char dirty:1;
- unsigned char byteswap:1;
- unsigned char readonly:1;
- unsigned char ungot:1;
- };
-
- stream_interface_t *funcs;
-
- /* stream-specific data */
- union {
- char *name;
- size_t maxsize;
- int rd; // pipe read descriptor
- };
- union {
- FILE *fptr;
- char *data;
- char *s;
- int wd; // pipe write descriptor
- };
- union {
- /* this is always a size in BYTES */
- size_t size;
- size_t len;
- };
- char local[N_STREAM_LOCAL];
-} stream_t;
-
-#include <stdio.h>
-
-stream_t *filestream_new(stream_t *s, char *fName,
- bool_t create, bool_t rewrite);
-stream_t *memstream_new(stream_t *s, size_t initsize);
-stream_t *pipestream_new(stream_t *s, int flags);
-stream_t *stream_fromfile(stream_t *s, FILE *f, char *name);
-//string_t *string_new(int len);
-//string_t *string_fromc(char *s);
-stream_t *memstream_copy(stream_t *s);
-void stream_free(stream_t *s);
-void stream_flush(stream_t *s);
-
-
-/* high level stream functions */
-
-/* 'all' means copy to end of stream */
-int stream_copy(stream_t *to, stream_t *from, size_t nbytes, bool_t all);
-
-int stream_put_num(stream_t *s, char *data, u_int32_t type);
-int stream_put_int(stream_t *s, int n);
-int stream_put_char(stream_t *s, u_int32_t wc);
-int stream_put_stringz(stream_t *s, char *str, bool_t nulterm);
-
-/* single-bit I/O - even works for mixed reads and writes.
- mixing bit-level I/O with normal byte stream I/O has undefined effects and
- will almost certainly destroy your file. however, it is safe to switch
- between bit and byte I/O if you call stream_flush in between. */
-void stream_put_bit(stream_t *s, int bit);
-
-/* warning: this uses a fixed-size buffer. it is intended only for printing
- normal things like "a= %d". if you might be printing a large buffer, you
- should use stream i/o functions directly. */
-int stream_printf(stream_t *s, char *format, ...);
-
-
-/* high level stream functions - input */
-
-int stream_get_num(stream_t *s, char *data, u_int32_t type);
-int stream_get_char(stream_t *s, u_int32_t *pwc);
-int stream_get_stringz(stream_t *dest, stream_t *src);
-int stream_get_stringn(stream_t *dest, stream_t *src, size_t c);
-int stream_readline(stream_t *dest, stream_t *s, char delim);
-int stream_getline(stream_t *s, char **pbuf, size_t *psz);
-/* returns # of bits read (0 or 1) */
-int stream_get_bit(stream_t *s, int *pbit);
-
-int stream_nextchar(stream_t *s);
-int stream_prevchar(stream_t *s);
-
-void stream_close(stream_t *s);
-
-/* TODO */
-// stream_fgetc
-// stream_ungetc
-
-/* get underlying file descriptors, -1 if none */
-int stream_readfd(stream_t *s);
-int stream_writefd(stream_t *s);
-
-/*
- low level stream functions
-
- Streams are intended to provide a uniform function interface to various
- kinds of byte streams.
-
- The eight low-level stream functions (below) are intended to be light weight.
- It must be easy to implement reasonably efficient higher-level stream
- functions, therefore any complexity required to make (for example) single
- byte reads and writes efficient must be implemented by the stream.
-
- Note that you can implement file streams using fread(), fwrite(), etc.
- because buffering is already implemented in every standard C library. These
- calls do not make system calls in general, and are perfectly fine to use.
-*/
-
-#define stream_seek(s, w) (s)->funcs->seek(s, w)
-#define stream_seek_end(s) (s)->funcs->seek_end(s)
-#define stream_skip(s, o) (s)->funcs->skip(s, o)
-#define stream_read(s, d, sz) (s)->funcs->read(s, (char*)d, sz)
-#define stream_write(s, d, sz) (s)->funcs->write(s, (char*)d, sz)
-#define stream_trunc(s, sz) (s)->funcs->trunc(s, sz)
-#define stream_eof(s) (s)->funcs->eof(s)
-
-
-STATIC_INLINE size_t stream_put_byte(stream_t *s, byte_t b)
-{
- return stream_write(s, (char*)&b, 1);
-}
-
-STATIC_INLINE size_t stream_get_byte(stream_t *s, byte_t *pb)
-{
- return stream_read(s, (char*)pb, 1);
-}
-
-#define stream_puts(s, str) stream_write(s, str, strlen(str))
-
-/*
- stream_take_buffer
-
- This lets you get the data of a stream without having to copy it. In order
- not to either lose the buffer or free it twice, this operation effectively
- empties the stream. In other words, size goes to 0, data becomes NULL.
- Whoever called the function takes full responsibility for the buffer.
- You must free it eventually.
- "size" gets set to the size of the data in the buffer.
-*/
-char *stream_take_buffer(stream_t *s, size_t *size);
-
-#endif
--- a/llt/attic/trash.c
+++ /dev/null
@@ -1,68 +1,0 @@
-/* moving data in small power-of-2 sized units */
-void copy_el(char *dest, char *src, size_t sz)
-{
- switch (sz) {
- case 16:
- *(int64_t*)&dest[0] = *(int64_t*)&src[0];
- *(int64_t*)&dest[8] = *(int64_t*)&src[8];
- break;
- case 8: *(int64_t*)dest = *(int64_t*)src; break;
- case 4: *(int32_t*)dest = *(int32_t*)src; break;
- case 2: *(int16_t*)dest = *(int16_t*)src; break;
- case 1: *dest = *src; break;
- }
-}
-
-void swap_el(char *a, char *b, size_t sz)
-{
- int64_t i64;
- int32_t i32;
- int16_t i16;
- int8_t i8;
- switch (sz) {
- case 16:
- i64 = *(int64_t*)&a[0];
- *(int64_t*)&a[0] = *(int64_t*)&b[0];
- *(int64_t*)&b[0] = i64;
- i64 = *(int64_t*)&a[8];
- *(int64_t*)&a[8] = *(int64_t*)&b[8];
- *(int64_t*)&b[8] = i64;
- break;
- case 8:
- i64 = *(int64_t*)a;
- *(int64_t*)a = *(int64_t*)b;
- *(int64_t*)b = i64;
- break;
- case 4:
- i32 = *(int32_t*)a;
- *(int32_t*)a = *(int32_t*)b;
- *(int32_t*)b = i32;
- break;
- case 2:
- i16 = *(int16_t*)a;
- *(int16_t*)a = *(int16_t*)b;
- *(int16_t*)b = i16;
- break;
- case 1:
- i8 = *a;
- *a = *b;
- *b = i8;
- break;
- }
-}
-
-void neg_any(void *dest, void *a, numerictype_t tag)
-{
- switch (tag) {
- case T_INT8: *(int8_t *)dest = -*(int8_t *)a; break;
- case T_UINT8: *(uint8_t *)dest = -*(uint8_t *)a; break;
- case T_INT16: *(int16_t *)dest = -*(int16_t *)a; break;
- case T_UINT16: *(uint16_t*)dest = -*(uint16_t*)a; break;
- case T_INT32: *(int32_t *)dest = -*(int32_t *)a; break;
- case T_UINT32: *(uint32_t*)dest = -*(uint32_t*)a; break;
- case T_INT64: *(int64_t *)dest = -*(int64_t *)a; break;
- case T_UINT64: *(uint64_t*)dest = -*(uint64_t*)a; break;
- case T_FLOAT: *(float *)dest = -*(float *)a; break;
- case T_DOUBLE: *(double *)dest = -*(double *)a; break;
- }
-}
--- a/llt/scrap
+++ /dev/null
@@ -1,176 +1,0 @@
-/* null stream */
-off_t null_seek(struct _stream *s, off_t where)
-{
- return -1;
-}
-
-off_t null_skip(struct _stream *s, off_t offs)
-{
- return 0;
-}
-
-off_t null_seek_end(struct _stream *s)
-{
- return -1;
-}
-
-size_t null_read(struct _stream *s, char *dest, size_t size)
-{
- return 0;
-}
-
-size_t null_write(struct _stream *s, char *data, size_t size)
-{
- return 0;
-}
-
-size_t null_trunc(struct _stream *s, size_t size)
-{
- return 0;
-}
-
-void null_flush(struct _stream *s)
-{
-}
-
-bool_t null_eof(struct _stream *s)
-{
- return true;
-}
-
-void free_null_stream(stream_t *s)
-{
-}
-
-DLLEXPORT stream_interface_t null_funcs =
- {free_null_stream, null_seek, null_seek_end, null_skip,
- null_read, null_write, null_trunc, null_eof, null_flush};
-
-stream_t *nullstream_new()
-{
- stream_t *s;
-
- s = (stream_t*)obj_alloc(stream_pool);
- s->funcs = &null_funcs;
- s->byteswap = false;
- s->bitpos = s->bitbuf = 0;
- s->pos = 0;
-
- return s;
-}
-
-void free_roms_stream(stream_t *s)
-{
- (void)s;
-}
-
-size_t roms_write(struct _stream *s, char *data, size_t size)
-{
- (void)s;
- (void)data;
- (void)size;
- return 0;
-}
-
-size_t roms_trunc(struct _stream *s, size_t size)
-{
- (void)size;
- return s->size;
-}
-
-void roms_flush(struct _stream *s)
-{
- s->bitpos = 0;
-}
-
-stream_interface_t roms_funcs =
- {free_roms_stream, ms_seek, ms_seek_end, ms_skip,
- ms_read, roms_write, roms_trunc, ms_eof, roms_flush};
-
-/* read-only memory stream */
-stream_t *romemstream_new(stream_t *s, char *data, size_t len)
-{
- memstream_new(s, 0);
-
- s->funcs = &roms_funcs;
-
- s->data = data;
- s->size = len;
- s->maxsize = len+1;
- s->pos = 0;
- s->bitpos = s->bitbuf = 0;
- s->byteswap = false;
-
- return s;
-}
-
-int stream_vput_int(stream_t *s, int nargs, ...)
-{
- u_int32_t val, i, c=0;
- va_list ap;
-
- va_start(ap, nargs);
- for(i=0; i < (unsigned)nargs; i++) {
- val = va_arg(ap, int);
- c += stream_put_int(s, val);
- }
- va_end(ap);
-
- return c;
-}
-
-// after this function you are guaranteed to be able to perform
-// operations of the kind requested.
-static int _ios_setstate(ios_t *s, iostate_t newstate)
-{
- if (s->state != newstate) {
- if (s->state == iost_none || s->bm == bm_mem || s->bm == bm_none) {
- }
- else if (s->state == iost_rd) {
- // reading -> writing; try to put back unused buffer data
- // todo: another possibility here is to seek back s->size bytes,
- // not move any data, and retain the ability to seek backwards
- // within the buffer. the downside to that would be redundant
- // writes of stuff that was already in the file.
- ios_skip(s, -(off_t)(s->size - s->bpos));
- // todo: if the seek fails...?
- _discard_partial_buffer(s);
- // note: bitpos is left alone, so if all goes well we pick up
- // writing exactly where we stopped reading.
- }
- else if (s->state == iost_wr) {
- ios_flush(s);
- }
- s->state = newstate;
- }
-
- // now make sure buffer is set up for the state we're in
- if (s->state == iost_wr) {
- // TODO: fill buffer if stenciling is requested
- }
- else if (s->state == iost_rd) {
- // TODO: fill buffer if needed
- }
-
- return 0;
-}
-
-
-/* convert double to int64 in software */
-int64_t double_to_int64(double d)
-{
- int64_t i;
- int ex;
- union ieee754_double dl;
-
- if (fabs(d) < 1) return 0;
-
- dl.d = d;
- ex = dl.ieee.exponent - IEEE754_DOUBLE_BIAS;
- // fill mantissa into bits 0 to 51
- i = ((((int64_t)dl.mantissa0)<<32) | ((int64_t)dl.mantissa1));
- if (ex < 52)
- i >>= (52-ex);
- else if (ex > 52)
- i <<= (ex-52);
-}