diff options
author | Jo-Philipp Wich <jow@openwrt.org> | 2009-07-09 15:04:27 +0000 |
---|---|---|
committer | Jo-Philipp Wich <jow@openwrt.org> | 2009-07-09 15:04:27 +0000 |
commit | d9d3c714351b82cfd387fc6f83d89591909312a2 (patch) | |
tree | ab085a92c2c21888fc4ffbd0c952f6614afc2cc2 /libs/lmo/src/lmo_lualib.c | |
parent | fb64c146094fc1f8d1cb33da171aa00e8b549dea (diff) |
libs: introduce lmo - Lua Machine Objects, an implementation of binary hash tables
Diffstat (limited to 'libs/lmo/src/lmo_lualib.c')
-rw-r--r-- | libs/lmo/src/lmo_lualib.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/libs/lmo/src/lmo_lualib.c b/libs/lmo/src/lmo_lualib.c new file mode 100644 index 0000000000..3f9170e887 --- /dev/null +++ b/libs/lmo/src/lmo_lualib.c @@ -0,0 +1,124 @@ +/* + * lmo - Lua Machine Objects - Lookup utility + * + * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lmo_lualib.h" + +extern char _lmo_error[1024]; + + +static int lmo_L_open(lua_State *L) { + const char *filename = luaL_checklstring(L, 1, NULL); + lmo_archive_t *ar, **udata; + + if( (ar = lmo_open(filename)) != NULL ) + { + if( (udata = lua_newuserdata(L, sizeof(lmo_archive_t *))) != NULL ) + { + *udata = ar; + luaL_getmetatable(L, LMO_ARCHIVE_META); + lua_setmetatable(L, -2); + return 1; + } + + lua_pushnil(L); + lua_pushstring(L, "out of memory"); + return 2; + } + + lua_pushnil(L); + lua_pushstring(L, lmo_error()); + return 2; +} + +static int lmo_L_hash(lua_State *L) { + const char *data = luaL_checkstring(L, 1); + uint32_t hash = sfh_hash(data, strlen(data)); + lua_pushnumber(L, hash); + return 1; +} + +static int lmo_L_lookup(lua_State *L) { + lmo_archive_t **ar = luaL_checkudata(L, 1, LMO_ARCHIVE_META); + lmo_entry_t *e = (*ar)->index; + const char *key = luaL_checkstring(L, 2); + uint32_t hash = sfh_hash(key, strlen(key)); + + while( e != NULL ) + { + if( e->key_id == hash ) + { + lua_pushlstring(L, &(*ar)->mmap[e->offset], e->length); + return 1; + } + + e = e->next; + } + + lua_pushnil(L); + return 1; +} + +static int lmo_L__gc(lua_State *L) { + lmo_archive_t **ar = luaL_checkudata(L, 1, LMO_ARCHIVE_META); + + if( (*ar) != NULL ) + lmo_close(*ar); + + *ar = NULL; + + return 0; +} + +static int lmo_L__tostring(lua_State *L) { + lmo_archive_t **ar = luaL_checkudata(L, 1, LMO_ARCHIVE_META); + lua_pushfstring(L, "LMO Archive (%d bytes)", (*ar)->length); + return 1; +} + + +/* method table */ +static const luaL_reg M[] = { + {"close", lmo_L__gc}, + {"lookup", lmo_L_lookup}, + {"__tostring", lmo_L__tostring}, + {"__gc", lmo_L__gc}, + {NULL, NULL} +}; + +/* module table */ +static const luaL_reg R[] = { + {"open", lmo_L_open}, + {"hash", lmo_L_hash}, + {NULL, NULL} +}; + +LUALIB_API int luaopen_lmo(lua_State *L) { + luaL_newmetatable(L, LMO_LUALIB_META); + luaL_register(L, NULL, R); + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + lua_setglobal(L, LMO_LUALIB_META); + + luaL_newmetatable(L, LMO_ARCHIVE_META); + luaL_register(L, NULL, M); + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + lua_setglobal(L, LMO_ARCHIVE_META); + + return 1; +} |