177 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			177 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
/* 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);
 | 
						|
}
 |