shithub: femtolisp

ref: 1ee81e2625d31562e3a43df2f935598e8dd31068
dir: /llt/scrap/

View raw version
/* 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);
}