-
Notifications
You must be signed in to change notification settings - Fork 1
/
buffer.c
71 lines (64 loc) · 1.88 KB
/
buffer.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <string.h>
#include "buffer.h"
void buffer_initialize(struct buffer *b, lua_State *L) {
b->L = L;
b->head = (struct block*)&b->stack;
b->head->p = 0;
b->head->len = INITIAL_SIZE;
b->head->next = NULL;
b->curr = b->head;
}
static struct block *_buffer_new_block(struct buffer *b) {
void *ud;
lua_Alloc alloc = lua_getallocf(b->L, &ud);
struct block *res = (struct block*)alloc(ud, NULL, 0, b->curr->len * 2 + sizeof(struct block));
res->p = 0;
res->len = b->curr->len * 2;
res->next = NULL;
return res;
}
void buffer_append(struct buffer *b, const char *data, size_t len) {
size_t space = b->curr->len - b->curr->p;
while (space < len) {
if (space > 0) {
memcpy(b->curr->data + b->curr->p, data, space);
data += space;
b->curr->p += space;
len -= space;
}
b->curr = b->curr->next = _buffer_new_block(b);
space = b->curr->len;
}
memcpy(b->curr->data + b->curr->p, data, len);
b->curr->p += len;
}
void buffer_free(struct buffer *b) {
void *ud;
lua_Alloc alloc = lua_getallocf(b->L, &ud);
struct block *p = b->head;
while (p) {
struct block *t = p->next;
if (p != (struct block*)&b->stack)
alloc(ud, p, p->len + sizeof(struct block), 0);
p = t;
}
}
void buffer_push_string(struct buffer *b) {
size_t size = buffer_size(b);
if (size <= INITIAL_SIZE) {
lua_pushlstring(b->L, b->head->data, size);
} else {
void *ud;
lua_Alloc alloc = lua_getallocf(b->L, &ud);
char *str = (char *)alloc(ud, NULL, 0, size);
char *s = str;
struct block *p = b->head;
while (p) {
memcpy(s, p->data, p->p);
s += p->p;
p = p->next;
}
lua_pushlstring(b->L, str, size);
alloc(ud, str, size, 0);
}
}