13 size_t alen; /* allocated size */ |
13 size_t alen; /* allocated size */ |
14 size_t blen; /* current content size */ |
14 size_t blen; /* current content size */ |
15 char buffer[]; |
15 char buffer[]; |
16 } ringbuffer; |
16 } ringbuffer; |
17 |
17 |
18 char readchar(ringbuffer *b) { |
18 static void writechar(ringbuffer *b, char c) { |
19 b->blen--; |
|
20 return b->buffer[(b->rpos++) % b->alen]; |
|
21 } |
|
22 |
|
23 void writechar(ringbuffer *b, char c) { |
|
24 b->blen++; |
19 b->blen++; |
25 b->buffer[(b->wpos++) % b->alen] = c; |
20 b->buffer[(b->wpos++) % b->alen] = c; |
26 } |
21 } |
27 |
22 |
28 /* make sure position counters stay within the allocation */ |
23 /* make sure position counters stay within the allocation */ |
29 void modpos(ringbuffer *b) { |
24 static void modpos(ringbuffer *b) { |
30 b->rpos = b->rpos % b->alen; |
25 b->rpos = b->rpos % b->alen; |
31 b->wpos = b->wpos % b->alen; |
26 b->wpos = b->wpos % b->alen; |
32 } |
27 } |
33 |
28 |
34 int find(ringbuffer *b, const char *s, size_t l) { |
29 static int find(ringbuffer *b, const char *s, size_t l) { |
35 size_t i, j; |
30 size_t i, j; |
36 int m; |
31 int m; |
37 |
32 |
38 if(b->rpos == b->wpos) { /* empty */ |
33 if(b->rpos == b->wpos) { /* empty */ |
39 return 0; |
34 return 0; |
62 |
57 |
63 /* |
58 /* |
64 * Find first position of a substring in buffer |
59 * Find first position of a substring in buffer |
65 * (buffer, string) -> number |
60 * (buffer, string) -> number |
66 */ |
61 */ |
67 int rb_find(lua_State *L) { |
62 static int rb_find(lua_State *L) { |
68 size_t l, m; |
63 size_t l, m; |
69 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
64 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
70 const char *s = luaL_checklstring(L, 2, &l); |
65 const char *s = luaL_checklstring(L, 2, &l); |
71 m = find(b, s, l); |
66 m = find(b, s, l); |
72 |
67 |
80 |
75 |
81 /* |
76 /* |
82 * Move read position forward without returning the data |
77 * Move read position forward without returning the data |
83 * (buffer, number) -> boolean |
78 * (buffer, number) -> boolean |
84 */ |
79 */ |
85 int rb_discard(lua_State *L) { |
80 static int rb_discard(lua_State *L) { |
86 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
81 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
87 size_t r = luaL_checkinteger(L, 2); |
82 size_t r = luaL_checkinteger(L, 2); |
88 |
83 |
89 if(r > b->blen) { |
84 if(r > b->blen) { |
90 lua_pushboolean(L, 0); |
85 lua_pushboolean(L, 0); |
101 |
96 |
102 /* |
97 /* |
103 * Read bytes from buffer |
98 * Read bytes from buffer |
104 * (buffer, number, boolean?) -> string |
99 * (buffer, number, boolean?) -> string |
105 */ |
100 */ |
106 int rb_read(lua_State *L) { |
101 static int rb_read(lua_State *L) { |
107 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
102 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
108 size_t r = luaL_checkinteger(L, 2); |
103 size_t r = luaL_checkinteger(L, 2); |
109 int peek = lua_toboolean(L, 3); |
104 int peek = lua_toboolean(L, 3); |
110 |
105 |
111 if(r > b->blen) { |
106 if(r > b->blen) { |
133 |
128 |
134 /* |
129 /* |
135 * Read buffer until first occurrence of a substring |
130 * Read buffer until first occurrence of a substring |
136 * (buffer, string) -> string |
131 * (buffer, string) -> string |
137 */ |
132 */ |
138 int rb_readuntil(lua_State *L) { |
133 static int rb_readuntil(lua_State *L) { |
139 size_t l, m; |
134 size_t l, m; |
140 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
135 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
141 const char *s = luaL_checklstring(L, 2, &l); |
136 const char *s = luaL_checklstring(L, 2, &l); |
142 m = find(b, s, l); |
137 m = find(b, s, l); |
143 |
138 |
152 |
147 |
153 /* |
148 /* |
154 * Write bytes into the buffer |
149 * Write bytes into the buffer |
155 * (buffer, string) -> integer |
150 * (buffer, string) -> integer |
156 */ |
151 */ |
157 int rb_write(lua_State *L) { |
152 static int rb_write(lua_State *L) { |
158 size_t l, w = 0; |
153 size_t l, w = 0; |
159 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
154 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
160 const char *s = luaL_checklstring(L, 2, &l); |
155 const char *s = luaL_checklstring(L, 2, &l); |
161 |
156 |
162 /* Does `l` bytes fit? */ |
157 /* Does `l` bytes fit? */ |
175 lua_pushinteger(L, w); |
170 lua_pushinteger(L, w); |
176 |
171 |
177 return 1; |
172 return 1; |
178 } |
173 } |
179 |
174 |
180 int rb_tostring(lua_State *L) { |
175 static int rb_tostring(lua_State *L) { |
181 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
176 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
182 lua_pushfstring(L, "ringbuffer: %p %d/%d", b, b->blen, b->alen); |
177 lua_pushfstring(L, "ringbuffer: %p %d/%d", b, b->blen, b->alen); |
183 return 1; |
178 return 1; |
184 } |
179 } |
185 |
180 |
186 int rb_length(lua_State *L) { |
181 static int rb_length(lua_State *L) { |
187 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
182 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
188 lua_pushinteger(L, b->blen); |
183 lua_pushinteger(L, b->blen); |
189 return 1; |
184 return 1; |
190 } |
185 } |
191 |
186 |
192 int rb_size(lua_State *L) { |
187 static int rb_size(lua_State *L) { |
193 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
188 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
194 lua_pushinteger(L, b->alen); |
189 lua_pushinteger(L, b->alen); |
195 return 1; |
190 return 1; |
196 } |
191 } |
197 |
192 |
198 int rb_free(lua_State *L) { |
193 static int rb_free(lua_State *L) { |
199 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
194 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
200 lua_pushinteger(L, b->alen - b->blen); |
195 lua_pushinteger(L, b->alen - b->blen); |
201 return 1; |
196 return 1; |
202 } |
197 } |
203 |
198 |
204 int rb_new(lua_State *L) { |
199 static int rb_new(lua_State *L) { |
205 size_t size = luaL_optinteger(L, 1, sysconf(_SC_PAGESIZE)); |
200 size_t size = luaL_optinteger(L, 1, sysconf(_SC_PAGESIZE)); |
206 ringbuffer *b = lua_newuserdata(L, sizeof(ringbuffer) + size); |
201 ringbuffer *b = lua_newuserdata(L, sizeof(ringbuffer) + size); |
207 |
202 |
208 b->rpos = 0; |
203 b->rpos = 0; |
209 b->wpos = 0; |
204 b->wpos = 0; |