factor/native/win32/read.c

132 lines
2.1 KiB
C
Raw Normal View History

2004-12-10 22:57:15 -05:00
#include "../factor.h"
void primitive_add_read_count_io_task (void)
{
callback_list = cons(dpop(), callback_list);
dpop(); dpop();
}
void primitive_add_read_line_io_task (void)
{
dpop(); dpop();
}
void primitive_can_read_count (void)
{
dpop(); dpop();
box_boolean(true);
}
void primitive_can_read_line (void)
{
dpop();
box_boolean(true);
}
void primitive_read_count_8 (void)
{
F_PORT *port;
F_FIXNUM len;
DWORD out_len;
char *buf;
F_SBUF *result;
unsigned int i;
maybe_garbage_collection();
2004-12-11 15:02:34 -05:00
2004-12-10 22:57:15 -05:00
port = untag_port(dpop());
len = to_fixnum(dpop());
buf = malloc(len);
if (!ReadFile((HANDLE)port->fd, buf, len, &out_len, NULL))
io_error(__FUNCTION__);
result = sbuf(out_len);
for (i = 0; i < out_len; ++i)
set_sbuf_nth(result, i, buf[i] & 0xFF);
free(buf);
dpush(tag_object(result));
}
2004-12-11 15:02:34 -05:00
static void fill_buffer(F_PORT *port)
2004-12-10 22:57:15 -05:00
{
DWORD read_len;
2004-12-11 15:02:34 -05:00
F_STRING *buffer = untag_string(port->buffer);
2004-12-10 22:57:15 -05:00
if (port->buf_pos)
return;
2004-12-11 15:02:34 -05:00
if (!ReadFile((HANDLE)port->fd, buffer+1, BUF_SIZE, &read_len, NULL))
2004-12-10 22:57:15 -05:00
io_error(__FUNCTION__);
port->buf_pos += read_len;
}
2004-12-11 15:02:34 -05:00
static void unfill_buffer(F_PORT *port, int len)
2004-12-10 22:57:15 -05:00
{
2004-12-11 15:02:34 -05:00
F_STRING *buffer = untag_string(port->buffer);
memmove(buffer+1, ((char *)(buffer+1))+len, port->buf_pos - len);
2004-12-10 22:57:15 -05:00
port->buf_pos -= len;
}
2004-12-11 15:02:34 -05:00
#define GETBUF(n) (bget((CELL)buffer + sizeof(F_STRING) + (n)))
2004-12-10 22:57:15 -05:00
void primitive_read_line_8 (void)
{
F_PORT *port;
F_SBUF *result;
2004-12-11 15:02:34 -05:00
F_STRING *buffer;
2004-12-10 22:57:15 -05:00
int i;
bool got_line = false;
maybe_garbage_collection();
port = untag_port(dpop());
2004-12-11 15:02:34 -05:00
buffer = untag_string(port->buffer);
result = sbuf(LINE_SIZE);
2004-12-10 22:57:15 -05:00
while (!got_line)
{
fill_buffer(port);
2004-12-11 15:02:34 -05:00
2004-12-10 22:57:15 -05:00
for (i = 0; i < port->buf_pos; ++i)
{
2004-12-11 15:02:34 -05:00
BYTE ch = GETBUF(i);
if (ch == '\r')
2004-12-10 22:57:15 -05:00
{
got_line = true;
2004-12-11 15:02:34 -05:00
if (i < port->buf_pos - 1 && GETBUF(i+1) == '\n')
2004-12-10 22:57:15 -05:00
++i;
++i;
break;
}
2004-12-11 15:02:34 -05:00
else if (ch == '\n')
2004-12-10 22:57:15 -05:00
{
got_line = true;
2004-12-11 15:02:34 -05:00
if (i < port->buf_pos - 1 && GETBUF(i+1) == '\r')
2004-12-10 22:57:15 -05:00
++i;
++i;
break;
}
2004-12-11 15:02:34 -05:00
set_sbuf_nth(result, result->top, ch);
2004-12-10 22:57:15 -05:00
}
if (i == 0)
got_line = true;
else
unfill_buffer(port, i);
}
if (result->top || i)
dpush(tag_object(result));
else
dpush(F);
}
2004-12-11 15:02:34 -05:00
#undef GETBUF