added sliceBuffer built-in
This commit is contained in:
+61
-16
@@ -4,9 +4,15 @@
|
||||
#include "objects.h"
|
||||
|
||||
typedef struct {
|
||||
Object base;
|
||||
int size;
|
||||
unsigned char *body;
|
||||
int size,
|
||||
refs;
|
||||
unsigned char data[];
|
||||
} BufferBody;
|
||||
|
||||
typedef struct {
|
||||
Object base;
|
||||
BufferBody *body;
|
||||
int offset, length;
|
||||
} BufferObject;
|
||||
|
||||
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)
|
||||
return NULL;
|
||||
|
||||
obj->size = size;
|
||||
obj->body = Heap_RawMalloc(heap, sizeof(unsigned char) * size, error);
|
||||
obj->offset = 0;
|
||||
obj->length = size;
|
||||
obj->body = Heap_RawMalloc(heap, sizeof(BufferBody) + sizeof(unsigned char) * size, error);
|
||||
|
||||
if(obj->body == 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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if(obj->type != &t_buffer)
|
||||
@@ -59,8 +104,8 @@ void *Object_GetBufferAddrAndSize(Object *obj, int *size, Error *error)
|
||||
BufferObject *buf = (BufferObject*) obj;
|
||||
|
||||
if(size)
|
||||
*size = buf->size;
|
||||
return buf->body;
|
||||
*size = buf->length;
|
||||
return buf->body->data + buf->offset;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if(idx < 0 || idx >= buffer->size)
|
||||
if(idx < 0 || idx >= buffer->length)
|
||||
{
|
||||
Error_Report(error, 0, "Out of range index");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned char byte = buffer->body[idx];
|
||||
unsigned char byte = buffer->body->data[buffer->offset + idx];
|
||||
|
||||
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);
|
||||
assert(error->occurred == 0);
|
||||
|
||||
if(idx < 0 || idx >= buffer->size)
|
||||
if(idx < 0 || idx >= buffer->length)
|
||||
{
|
||||
Error_Report(error, 0, "Out of range index");
|
||||
return NULL;
|
||||
@@ -124,7 +169,7 @@ static _Bool insert(Object *self, Object *key, Object *val, Heap *heap, Error *e
|
||||
if(error->occurred == 1)
|
||||
return 0;
|
||||
|
||||
buffer->body[idx] = byte;
|
||||
buffer->body->data[buffer->offset + idx] = byte;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -132,7 +177,7 @@ static int count(Object *self)
|
||||
{
|
||||
BufferObject *buffer = (BufferObject*) self;
|
||||
|
||||
return buffer->size;
|
||||
return buffer->length;
|
||||
}
|
||||
|
||||
static void print(Object *self, FILE *fp)
|
||||
@@ -141,11 +186,11 @@ static void print(Object *self, FILE *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;
|
||||
|
||||
byte = buffer->body[i];
|
||||
byte = buffer->body->data[buffer->offset + i];
|
||||
low = byte & 0xf;
|
||||
high = byte >> 4;
|
||||
|
||||
@@ -159,7 +204,7 @@ static void print(Object *self, FILE *fp)
|
||||
|
||||
fprintf(fp, "%c%c", c1, c2);
|
||||
|
||||
if(i+1 < buffer->size)
|
||||
if(i+1 < buffer->length)
|
||||
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_NewBuffer(int size, 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_FromBool (_Bool val, Heap *heap, Error *error);
|
||||
|
||||
Reference in New Issue
Block a user