Mercurial > prosody-hg
comparison util-src/ringbuffer.c @ 7828:b4a08a514ebc
util.ringbuffer: Allocate buffer itself as part of userdata (simpler, single allocation, no need for __gc)
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sun, 22 Jan 2017 09:23:10 +0100 |
| parents | db15e9f6d77f |
| children | a809dcfd0c5b |
comparison
equal
deleted
inserted
replaced
| 7827:db15e9f6d77f | 7828:b4a08a514ebc |
|---|---|
| 11 typedef struct { | 11 typedef struct { |
| 12 size_t rpos; /* read position */ | 12 size_t rpos; /* read position */ |
| 13 size_t wpos; /* write position */ | 13 size_t wpos; /* write position */ |
| 14 size_t alen; /* allocated size */ | 14 size_t alen; /* allocated size */ |
| 15 size_t blen; /* current content size */ | 15 size_t blen; /* current content size */ |
| 16 char* buffer; | 16 char buffer[]; |
| 17 } ringbuffer; | 17 } ringbuffer; |
| 18 | 18 |
| 19 char readchar(ringbuffer* b) { | 19 char readchar(ringbuffer* b) { |
| 20 b->blen--; | 20 b->blen--; |
| 21 return b->buffer[(b->rpos++) % b->alen]; | 21 return b->buffer[(b->rpos++) % b->alen]; |
| 164 return 1; | 164 return 1; |
| 165 } | 165 } |
| 166 | 166 |
| 167 int rb_new(lua_State* L) { | 167 int rb_new(lua_State* L) { |
| 168 size_t size = luaL_optinteger(L, 1, sysconf(_SC_PAGESIZE)); | 168 size_t size = luaL_optinteger(L, 1, sysconf(_SC_PAGESIZE)); |
| 169 ringbuffer* b = lua_newuserdata(L, sizeof(ringbuffer)); | 169 ringbuffer *b = lua_newuserdata(L, sizeof(ringbuffer) + size); |
| 170 | |
| 170 b->rpos = 0; | 171 b->rpos = 0; |
| 171 b->wpos = 0; | 172 b->wpos = 0; |
| 172 b->alen = size; | 173 b->alen = size; |
| 173 b->blen = 0; | 174 b->blen = 0; |
| 174 b->buffer = malloc(size); | |
| 175 | |
| 176 if(b->buffer == NULL) { | |
| 177 return 0; | |
| 178 } | |
| 179 | 175 |
| 180 luaL_getmetatable(L, "ringbuffer_mt"); | 176 luaL_getmetatable(L, "ringbuffer_mt"); |
| 181 lua_setmetatable(L, -2); | 177 lua_setmetatable(L, -2); |
| 182 | 178 |
| 183 return 1; | 179 return 1; |
| 184 } | |
| 185 | |
| 186 int rb_gc(lua_State* L) { | |
| 187 ringbuffer* b = luaL_checkudata(L, 1, "ringbuffer_mt"); | |
| 188 | |
| 189 if(b->buffer != NULL) { | |
| 190 free(b->buffer); | |
| 191 } | |
| 192 | |
| 193 return 0; | |
| 194 } | 180 } |
| 195 | 181 |
| 196 int luaopen_util_ringbuffer(lua_State* L) { | 182 int luaopen_util_ringbuffer(lua_State* L) { |
| 197 #if (LUA_VERSION_NUM > 501) | 183 #if (LUA_VERSION_NUM > 501) |
| 198 luaL_checkversion(L); | 184 luaL_checkversion(L); |
| 200 if(luaL_newmetatable(L, "ringbuffer_mt")) { | 186 if(luaL_newmetatable(L, "ringbuffer_mt")) { |
| 201 lua_pushcfunction(L, rb_tostring); | 187 lua_pushcfunction(L, rb_tostring); |
| 202 lua_setfield(L, -2, "__tostring"); | 188 lua_setfield(L, -2, "__tostring"); |
| 203 lua_pushcfunction(L, rb_length); | 189 lua_pushcfunction(L, rb_length); |
| 204 lua_setfield(L, -2, "__len"); | 190 lua_setfield(L, -2, "__len"); |
| 205 lua_pushcfunction(L, rb_gc); | |
| 206 lua_setfield(L, -2, "__gc"); | |
| 207 | 191 |
| 208 lua_newtable(L); /* __index */ | 192 lua_newtable(L); /* __index */ |
| 209 { | 193 { |
| 210 lua_pushcfunction(L, rb_find); | 194 lua_pushcfunction(L, rb_find); |
| 211 lua_setfield(L, -2, "find"); | 195 lua_setfield(L, -2, "find"); |
