X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=libs%2Flmo%2Fsrc%2Flmo_lualib.c;h=59d88a15eba019f37b72fd6b8ccbb3dc0d7b530b;hb=3194662054cebfefc48c7ff3d3a5d7a3aa988b9a;hp=3f9170e8873ffbc4e8d6c56b2a38af2b4283d5bf;hpb=d9d3c714351b82cfd387fc6f83d89591909312a2;p=oweals%2Fluci.git diff --git a/libs/lmo/src/lmo_lualib.c b/libs/lmo/src/lmo_lualib.c index 3f9170e88..59d88a15e 100644 --- a/libs/lmo/src/lmo_lualib.c +++ b/libs/lmo/src/lmo_lualib.c @@ -1,5 +1,5 @@ /* - * lmo - Lua Machine Objects - Lookup utility + * lmo - Lua Machine Objects - Lua binding * * Copyright (C) 2009 Jo-Philipp Wich * @@ -35,6 +35,7 @@ static int lmo_L_open(lua_State *L) { return 1; } + lmo_close(ar); lua_pushnil(L); lua_pushstring(L, "out of memory"); return 2; @@ -48,22 +49,44 @@ static int lmo_L_open(lua_State *L) { 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); + lua_pushinteger(L, (lua_Integer)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)); +static lmo_luaentry_t *_lmo_push_entry(lua_State *L) { + lmo_luaentry_t *le; + + if( (le = lua_newuserdata(L, sizeof(lmo_luaentry_t))) != NULL ) + { + luaL_getmetatable(L, LMO_ENTRY_META); + lua_setmetatable(L, -2); + + return le; + } + + return NULL; +} + +static int _lmo_lookup(lua_State *L, lmo_archive_t *ar, uint32_t hash) { + lmo_entry_t *e = ar->index; + lmo_luaentry_t *le = NULL; while( e != NULL ) { if( e->key_id == hash ) { - lua_pushlstring(L, &(*ar)->mmap[e->offset], e->length); - return 1; + if( (le = _lmo_push_entry(L)) != NULL ) + { + le->archive = ar; + le->entry = e; + return 1; + } + else + { + lua_pushnil(L); + lua_pushstring(L, "out of memory"); + return 2; + } } e = e->next; @@ -73,6 +96,38 @@ static int lmo_L_lookup(lua_State *L) { return 1; } +static int lmo_L_get(lua_State *L) { + lmo_archive_t **ar = luaL_checkudata(L, 1, LMO_ARCHIVE_META); + uint32_t hash = (uint32_t) luaL_checkinteger(L, 2); + return _lmo_lookup(L, *ar, hash); +} + +static int lmo_L_lookup(lua_State *L) { + lmo_archive_t **ar = luaL_checkudata(L, 1, LMO_ARCHIVE_META); + const char *key = luaL_checkstring(L, 2); + uint32_t hash = sfh_hash(key, strlen(key)); + return _lmo_lookup(L, *ar, hash); +} + +static int lmo_L_foreach(lua_State *L) { + lmo_archive_t **ar = luaL_checkudata(L, 1, LMO_ARCHIVE_META); + lmo_entry_t *e = (*ar)->index; + + if( lua_isfunction(L, 2) ) + { + while( e != NULL ) + { + lua_pushvalue(L, 2); + lua_pushinteger(L, e->key_id); + lua_pushlstring(L, &(*ar)->mmap[e->offset], e->length); + lua_pcall(L, 2, 0, 0); + e = e->next; + } + } + + return 0; +} + static int lmo_L__gc(lua_State *L) { lmo_archive_t **ar = luaL_checkudata(L, 1, LMO_ARCHIVE_META); @@ -91,13 +146,69 @@ static int lmo_L__tostring(lua_State *L) { } -/* method table */ +static int _lmo_convert_entry(lua_State *L, int idx) { + lmo_luaentry_t *le = luaL_checkudata(L, idx, LMO_ENTRY_META); + + lua_pushlstring(L, + &le->archive->mmap[le->entry->offset], + le->entry->length + ); + + return 1; +} + +static int lmo_L_entry__tostring(lua_State *L) { + return _lmo_convert_entry(L, 1); +} + +static int lmo_L_entry__concat(lua_State *L) { + if( lua_isuserdata(L, 1) ) + _lmo_convert_entry(L, 1); + else + lua_pushstring(L, lua_tostring(L, 1)); + + if( lua_isuserdata(L, 2) ) + _lmo_convert_entry(L, 2); + else + lua_pushstring(L, lua_tostring(L, 2)); + + lua_concat(L, 2); + + return 1; +} + +static int lmo_L_entry__len(lua_State *L) { + lmo_luaentry_t *le = luaL_checkudata(L, 1, LMO_ENTRY_META); + lua_pushinteger(L, le->entry->length); + return 1; +} + +static int lmo_L_entry__gc(lua_State *L) { + lmo_luaentry_t *le = luaL_checkudata(L, 1, LMO_ENTRY_META); + le->archive = NULL; + le->entry = NULL; + return 0; +} + + +/* lmo method table */ static const luaL_reg M[] = { - {"close", lmo_L__gc}, - {"lookup", lmo_L_lookup}, + {"close", lmo_L__gc}, + {"get", lmo_L_get}, + {"lookup", lmo_L_lookup}, + {"foreach", lmo_L_foreach}, {"__tostring", lmo_L__tostring}, - {"__gc", lmo_L__gc}, - {NULL, NULL} + {"__gc", lmo_L__gc}, + {NULL, NULL} +}; + +/* lmo.entry method table */ +static const luaL_reg E[] = { + {"__tostring", lmo_L_entry__tostring}, + {"__concat", lmo_L_entry__concat}, + {"__len", lmo_L_entry__len}, + {"__gc", lmo_L_entry__gc}, + {NULL, NULL} }; /* module table */ @@ -108,17 +219,19 @@ static const luaL_reg R[] = { }; 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); + luaL_newmetatable(L, LMO_ENTRY_META); + luaL_register(L, NULL, E); + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + lua_setglobal(L, LMO_ENTRY_META); + + luaL_register(L, LMO_LUALIB_META, R); + return 1; }