added sliceBuffer built-in
This commit is contained in:
+24
-8
@@ -21,7 +21,13 @@ fun startServer(callbacks, port, backlog)
|
|||||||
return none;
|
return none;
|
||||||
}
|
}
|
||||||
|
|
||||||
if net.bind(fd, {sin_family: net.AF_INET, sin_port: net.htons(port), sin_addr: {s_addr: net.htonl(net.INADDR_ANY)}}) != 0:
|
if net.bind(fd, {
|
||||||
|
sin_family: net.AF_INET,
|
||||||
|
sin_port: net.htons(port),
|
||||||
|
sin_addr: {
|
||||||
|
s_addr: net.htonl(net.INADDR_ANY)
|
||||||
|
}
|
||||||
|
}) != 0:
|
||||||
{
|
{
|
||||||
print('Failed to bind.\n');
|
print('Failed to bind.\n');
|
||||||
return none;
|
return none;
|
||||||
@@ -33,15 +39,25 @@ fun startServer(callbacks, port, backlog)
|
|||||||
return none;
|
return none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
on_datain = callbacks.on_datain;
|
on_datain = callbacks.on_datain;
|
||||||
on_connect = callbacks.on_connect;
|
on_connect = callbacks.on_connect;
|
||||||
on_disconnect = callbacks.on_disconnect;
|
on_disconnect = callbacks.on_disconnect;
|
||||||
|
|
||||||
if on_datain == none: fun on_datain() none;
|
if on_datain == none:
|
||||||
if on_connect == none: fun on_connect() none;
|
fun on_datain()
|
||||||
if on_disconnect == none: fun on_disconnect() none;
|
none;
|
||||||
|
|
||||||
buffer = newBuffer(16);
|
if on_connect == none:
|
||||||
|
fun on_connect()
|
||||||
|
none;
|
||||||
|
|
||||||
|
if on_disconnect == none:
|
||||||
|
fun on_disconnect()
|
||||||
|
none;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = newBuffer(1024);
|
||||||
|
|
||||||
while true:
|
while true:
|
||||||
{
|
{
|
||||||
@@ -67,7 +83,7 @@ fun startServer(callbacks, port, backlog)
|
|||||||
else if n == 0:
|
else if n == 0:
|
||||||
on_disconnect(addr_str);
|
on_disconnect(addr_str);
|
||||||
else
|
else
|
||||||
on_datain(addr_str, buffer, n);
|
on_datain(addr_str, sliceBuffer(buffer, 0, n));
|
||||||
}
|
}
|
||||||
while n > 0;
|
while n > 0;
|
||||||
}
|
}
|
||||||
@@ -78,9 +94,9 @@ fun on_connect(addr)
|
|||||||
print(addr, ' connected.\n');
|
print(addr, ' connected.\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
fun on_datain(addr, buf, len)
|
fun on_datain(addr, data)
|
||||||
{
|
{
|
||||||
print('Received ', len, ' bytes from ', addr);
|
print('Received ', count(data), ' bytes from ', addr, '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
fun on_disconnect(addr)
|
fun on_disconnect(addr)
|
||||||
|
|||||||
+23
-1
@@ -14,6 +14,7 @@ static Object *bin_count (Runtime *runtime, Object **argv, unsigned int argc, Er
|
|||||||
static Object *bin_assert(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
|
static Object *bin_assert(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
|
||||||
static Object *bin_strcat(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
|
static Object *bin_strcat(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
|
||||||
static Object *bin_newBuffer(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
|
static Object *bin_newBuffer(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
|
||||||
|
static Object *bin_sliceBuffer(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Object base;
|
Object base;
|
||||||
@@ -79,6 +80,14 @@ static Object *select_(Object *self, Object *key, Heap *heap, Error *err)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case PAIR(sizeof("sliceBuffer")-1, 's'):
|
||||||
|
{
|
||||||
|
if(!strcmp(s, "sliceBuffer"))
|
||||||
|
return Object_FromNativeFunction(bm->runtime, bin_sliceBuffer, 3, heap, err);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
case PAIR(sizeof("net")-1, 'n'):
|
case PAIR(sizeof("net")-1, 'n'):
|
||||||
{
|
{
|
||||||
if(!strcmp(s, "net"))
|
if(!strcmp(s, "net"))
|
||||||
@@ -210,10 +219,23 @@ static Object *bin_newBuffer(Runtime *runtime, Object **argv, unsigned int argc,
|
|||||||
{
|
{
|
||||||
assert(argc == 1);
|
assert(argc == 1);
|
||||||
|
|
||||||
int size = Object_ToInt(argv[0], error);
|
long long int size = Object_ToInt(argv[0], error);
|
||||||
|
|
||||||
if(error->occurred == 1)
|
if(error->occurred == 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return Object_NewBuffer(size, Runtime_GetHeap(runtime), error);
|
return Object_NewBuffer(size, Runtime_GetHeap(runtime), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Object *bin_sliceBuffer(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
|
||||||
|
{
|
||||||
|
assert(argc == 3);
|
||||||
|
|
||||||
|
long long int offset = Object_ToInt(argv[1], error);
|
||||||
|
if(error->occurred == 1) return NULL;
|
||||||
|
|
||||||
|
long long int length = Object_ToInt(argv[2], error);
|
||||||
|
if(error->occurred == 1) return NULL;
|
||||||
|
|
||||||
|
return Object_SliceBuffer(argv[0], offset, length, Runtime_GetHeap(runtime), error);
|
||||||
|
}
|
||||||
+60
-15
@@ -3,10 +3,16 @@
|
|||||||
#include "../utils/defs.h"
|
#include "../utils/defs.h"
|
||||||
#include "objects.h"
|
#include "objects.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int size,
|
||||||
|
refs;
|
||||||
|
unsigned char data[];
|
||||||
|
} BufferBody;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Object base;
|
Object base;
|
||||||
int size;
|
BufferBody *body;
|
||||||
unsigned char *body;
|
int offset, length;
|
||||||
} BufferObject;
|
} BufferObject;
|
||||||
|
|
||||||
static Object *select(Object *self, Object *key, Heap *heap, Error *err);
|
static Object *select(Object *self, Object *key, Heap *heap, Error *err);
|
||||||
@@ -36,18 +42,57 @@ Object *Object_NewBuffer(int size, Heap *heap, Error *error)
|
|||||||
if(obj == NULL)
|
if(obj == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
obj->size = size;
|
obj->offset = 0;
|
||||||
obj->body = Heap_RawMalloc(heap, sizeof(unsigned char) * size, error);
|
obj->length = size;
|
||||||
|
obj->body = Heap_RawMalloc(heap, sizeof(BufferBody) + sizeof(unsigned char) * size, error);
|
||||||
|
|
||||||
if(obj->body == NULL)
|
if(obj->body == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
memset(obj->body, 0, size);
|
obj->body->size = size;
|
||||||
|
obj->body->refs = 1;
|
||||||
|
memset(obj->body->data, 0, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (Object*) obj;
|
return (Object*) obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object *Object_SliceBuffer(Object *buffer, int offset, int length, Heap *heap, Error *error)
|
||||||
|
{
|
||||||
|
if(buffer->type != &t_buffer)
|
||||||
|
{
|
||||||
|
Error_Report(error, 0, "Not a buffer");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferObject *original = (BufferObject*) buffer;
|
||||||
|
BufferObject *slice = (BufferObject*) Heap_Malloc(heap, &t_buffer, error);
|
||||||
|
|
||||||
|
if(offset < 0 || offset >= original->length)
|
||||||
|
{
|
||||||
|
Error_Report(error, 0, "offset out of range");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(length < 0 || length >= original->length)
|
||||||
|
{
|
||||||
|
Error_Report(error, 0, "length out of range");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(offset + length > original->length)
|
||||||
|
{
|
||||||
|
Error_Report(error, 0, "slice out of range");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
slice->offset = original->offset + offset;
|
||||||
|
slice->length = length;
|
||||||
|
slice->body = original->body;
|
||||||
|
slice->body->refs += 1;
|
||||||
|
return (Object*) slice;
|
||||||
|
}
|
||||||
|
|
||||||
void *Object_GetBufferAddrAndSize(Object *obj, int *size, Error *error)
|
void *Object_GetBufferAddrAndSize(Object *obj, int *size, Error *error)
|
||||||
{
|
{
|
||||||
if(obj->type != &t_buffer)
|
if(obj->type != &t_buffer)
|
||||||
@@ -59,8 +104,8 @@ void *Object_GetBufferAddrAndSize(Object *obj, int *size, Error *error)
|
|||||||
BufferObject *buf = (BufferObject*) obj;
|
BufferObject *buf = (BufferObject*) obj;
|
||||||
|
|
||||||
if(size)
|
if(size)
|
||||||
*size = buf->size;
|
*size = buf->length;
|
||||||
return buf->body;
|
return buf->body->data + buf->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object *select(Object *self, Object *key, Heap *heap, Error *error)
|
static Object *select(Object *self, Object *key, Heap *heap, Error *error)
|
||||||
@@ -82,13 +127,13 @@ static Object *select(Object *self, Object *key, Heap *heap, Error *error)
|
|||||||
|
|
||||||
BufferObject *buffer = (BufferObject*) self;
|
BufferObject *buffer = (BufferObject*) self;
|
||||||
|
|
||||||
if(idx < 0 || idx >= buffer->size)
|
if(idx < 0 || idx >= buffer->length)
|
||||||
{
|
{
|
||||||
Error_Report(error, 0, "Out of range index");
|
Error_Report(error, 0, "Out of range index");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char byte = buffer->body[idx];
|
unsigned char byte = buffer->body->data[buffer->offset + idx];
|
||||||
|
|
||||||
return Object_FromInt(byte, heap, error);
|
return Object_FromInt(byte, heap, error);
|
||||||
}
|
}
|
||||||
@@ -113,7 +158,7 @@ static _Bool insert(Object *self, Object *key, Object *val, Heap *heap, Error *e
|
|||||||
int idx = Object_ToInt(key, error);
|
int idx = Object_ToInt(key, error);
|
||||||
assert(error->occurred == 0);
|
assert(error->occurred == 0);
|
||||||
|
|
||||||
if(idx < 0 || idx >= buffer->size)
|
if(idx < 0 || idx >= buffer->length)
|
||||||
{
|
{
|
||||||
Error_Report(error, 0, "Out of range index");
|
Error_Report(error, 0, "Out of range index");
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -124,7 +169,7 @@ static _Bool insert(Object *self, Object *key, Object *val, Heap *heap, Error *e
|
|||||||
if(error->occurred == 1)
|
if(error->occurred == 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
buffer->body[idx] = byte;
|
buffer->body->data[buffer->offset + idx] = byte;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +177,7 @@ static int count(Object *self)
|
|||||||
{
|
{
|
||||||
BufferObject *buffer = (BufferObject*) self;
|
BufferObject *buffer = (BufferObject*) self;
|
||||||
|
|
||||||
return buffer->size;
|
return buffer->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print(Object *self, FILE *fp)
|
static void print(Object *self, FILE *fp)
|
||||||
@@ -141,11 +186,11 @@ static void print(Object *self, FILE *fp)
|
|||||||
|
|
||||||
fprintf(fp, "[");
|
fprintf(fp, "[");
|
||||||
|
|
||||||
for(int i = 0; i < buffer->size; i += 1)
|
for(int i = 0; i < buffer->length; i += 1)
|
||||||
{
|
{
|
||||||
unsigned char byte, low, high;
|
unsigned char byte, low, high;
|
||||||
|
|
||||||
byte = buffer->body[i];
|
byte = buffer->body->data[buffer->offset + i];
|
||||||
low = byte & 0xf;
|
low = byte & 0xf;
|
||||||
high = byte >> 4;
|
high = byte >> 4;
|
||||||
|
|
||||||
@@ -159,7 +204,7 @@ static void print(Object *self, FILE *fp)
|
|||||||
|
|
||||||
fprintf(fp, "%c%c", c1, c2);
|
fprintf(fp, "%c%c", c1, c2);
|
||||||
|
|
||||||
if(i+1 < buffer->size)
|
if(i+1 < buffer->length)
|
||||||
fprintf(fp, ", ");
|
fprintf(fp, ", ");
|
||||||
}
|
}
|
||||||
fprintf(fp, "]");
|
fprintf(fp, "]");
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ Object* Object_NewList(int capacity, Heap *heap, Error *error);
|
|||||||
Object* Object_NewNone(Heap *heap, Error *error);
|
Object* Object_NewNone(Heap *heap, Error *error);
|
||||||
Object* Object_NewBuffer(int size, Heap *heap, Error *error);
|
Object* Object_NewBuffer(int size, Heap *heap, Error *error);
|
||||||
Object* Object_NewClosure(Object *parent, Object *new_map, Heap *heap, Error *error);
|
Object* Object_NewClosure(Object *parent, Object *new_map, Heap *heap, Error *error);
|
||||||
|
Object* Object_SliceBuffer(Object *buffer, int offset, int length, Heap *heap, Error *error);
|
||||||
|
|
||||||
Object* Object_FromInt (long long int val, Heap *heap, Error *error);
|
Object* Object_FromInt (long long int val, Heap *heap, Error *error);
|
||||||
Object* Object_FromBool (_Bool val, Heap *heap, Error *error);
|
Object* Object_FromBool (_Bool val, Heap *heap, Error *error);
|
||||||
|
|||||||
Reference in New Issue
Block a user