2 * lmo - Lua Machine Objects - Lua binding
4 * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 #include "lmo_lualib.h"
21 extern char _lmo_error
[1024];
24 static int lmo_L_open(lua_State
*L
) {
25 const char *filename
= luaL_checklstring(L
, 1, NULL
);
26 lmo_archive_t
*ar
, **udata
;
28 if( (ar
= lmo_open(filename
)) != NULL
)
30 if( (udata
= lua_newuserdata(L
, sizeof(lmo_archive_t
*))) != NULL
)
33 luaL_getmetatable(L
, LMO_ARCHIVE_META
);
34 lua_setmetatable(L
, -2);
40 lua_pushstring(L
, "out of memory");
45 lua_pushstring(L
, lmo_error());
49 static int lmo_L_hash(lua_State
*L
) {
50 const char *data
= luaL_checkstring(L
, 1);
51 uint32_t hash
= sfh_hash(data
, strlen(data
));
52 lua_pushinteger(L
, (lua_Integer
)hash
);
56 static lmo_luaentry_t
*_lmo_push_entry(lua_State
*L
) {
59 if( (le
= lua_newuserdata(L
, sizeof(lmo_luaentry_t
))) != NULL
)
61 luaL_getmetatable(L
, LMO_ENTRY_META
);
62 lua_setmetatable(L
, -2);
70 static int _lmo_lookup(lua_State
*L
, lmo_archive_t
*ar
, uint32_t hash
) {
71 lmo_entry_t
*e
= ar
->index
;
72 lmo_luaentry_t
*le
= NULL
;
76 if( e
->key_id
== hash
)
78 if( (le
= _lmo_push_entry(L
)) != NULL
)
87 lua_pushstring(L
, "out of memory");
99 static int lmo_L_get(lua_State
*L
) {
100 lmo_archive_t
**ar
= luaL_checkudata(L
, 1, LMO_ARCHIVE_META
);
101 uint32_t hash
= (uint32_t) luaL_checkinteger(L
, 2);
102 return _lmo_lookup(L
, *ar
, hash
);
105 static int lmo_L_lookup(lua_State
*L
) {
106 lmo_archive_t
**ar
= luaL_checkudata(L
, 1, LMO_ARCHIVE_META
);
107 const char *key
= luaL_checkstring(L
, 2);
108 uint32_t hash
= sfh_hash(key
, strlen(key
));
109 return _lmo_lookup(L
, *ar
, hash
);
112 static int lmo_L_foreach(lua_State
*L
) {
113 lmo_archive_t
**ar
= luaL_checkudata(L
, 1, LMO_ARCHIVE_META
);
114 lmo_entry_t
*e
= (*ar
)->index
;
116 if( lua_isfunction(L
, 2) )
121 lua_pushinteger(L
, e
->key_id
);
122 lua_pushlstring(L
, &(*ar
)->mmap
[e
->offset
], e
->length
);
123 lua_pcall(L
, 2, 0, 0);
131 static int lmo_L__gc(lua_State
*L
) {
132 lmo_archive_t
**ar
= luaL_checkudata(L
, 1, LMO_ARCHIVE_META
);
142 static int lmo_L__tostring(lua_State
*L
) {
143 lmo_archive_t
**ar
= luaL_checkudata(L
, 1, LMO_ARCHIVE_META
);
144 lua_pushfstring(L
, "LMO Archive (%d bytes)", (*ar
)->length
);
149 static int _lmo_convert_entry(lua_State
*L
, int idx
) {
150 lmo_luaentry_t
*le
= luaL_checkudata(L
, idx
, LMO_ENTRY_META
);
153 &le
->archive
->mmap
[le
->entry
->offset
],
160 static int lmo_L_entry__tostring(lua_State
*L
) {
161 return _lmo_convert_entry(L
, 1);
164 static int lmo_L_entry__concat(lua_State
*L
) {
165 if( lua_isuserdata(L
, 1) )
166 _lmo_convert_entry(L
, 1);
168 lua_pushstring(L
, lua_tostring(L
, 1));
170 if( lua_isuserdata(L
, 2) )
171 _lmo_convert_entry(L
, 2);
173 lua_pushstring(L
, lua_tostring(L
, 2));
180 static int lmo_L_entry__len(lua_State
*L
) {
181 lmo_luaentry_t
*le
= luaL_checkudata(L
, 1, LMO_ENTRY_META
);
182 lua_pushinteger(L
, le
->entry
->length
);
186 static int lmo_L_entry__gc(lua_State
*L
) {
187 lmo_luaentry_t
*le
= luaL_checkudata(L
, 1, LMO_ENTRY_META
);
194 /* lmo method table */
195 static const luaL_reg M
[] = {
196 {"close", lmo_L__gc
},
198 {"lookup", lmo_L_lookup
},
199 {"foreach", lmo_L_foreach
},
200 {"__tostring", lmo_L__tostring
},
205 /* lmo.entry method table */
206 static const luaL_reg E
[] = {
207 {"__tostring", lmo_L_entry__tostring
},
208 {"__concat", lmo_L_entry__concat
},
209 {"__len", lmo_L_entry__len
},
210 {"__gc", lmo_L_entry__gc
},
215 static const luaL_reg R
[] = {
216 {"open", lmo_L_open
},
217 {"hash", lmo_L_hash
},
221 LUALIB_API
int luaopen_lmo(lua_State
*L
) {
222 luaL_newmetatable(L
, LMO_ARCHIVE_META
);
223 luaL_register(L
, NULL
, M
);
224 lua_pushvalue(L
, -1);
225 lua_setfield(L
, -2, "__index");
226 lua_setglobal(L
, LMO_ARCHIVE_META
);
228 luaL_newmetatable(L
, LMO_ENTRY_META
);
229 luaL_register(L
, NULL
, E
);
230 lua_pushvalue(L
, -1);
231 lua_setfield(L
, -2, "__index");
232 lua_setglobal(L
, LMO_ENTRY_META
);
234 luaL_register(L
, LMO_LUALIB_META
, R
);