/* * lmo - Lua Machine Objects - Lookup utility * * Copyright (C) 2009 Jo-Philipp Wich * * 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; }