/* put the item back into the free list */
void free_closure(void *p)
{
ITEM *item = (ITEM *)p;
item->next = free_list;
free_list = item;
}
/* return one item from the free list, allocating more if needed */
void *malloc_closure(void)
{
ITEM *item;
if (!free_list)
more_core();
if (!free_list)
return NULL;
item = free_list;
free_list = item->next;
return item;
}
break;
case AT_CALLBACK:
p = *((void**)&b[offset]);
p ? alien_makefunction(L, NULL, p, NULL) : lua_pushnil(L);
break;
case AT_PTR:
p = *((void**)&b[offset]);
p ? lua_pushlightuserdata(L, p) : lua_pushnil(L);
break;
default:
luaL_error(L, "alien: unknown type in buffer:get");
}
}
return 1;
}
static int alien_buffer_put(lua_State *L) {
static const int types[] = {AT_VOID, AT_INT, AT_DOUBLE, AT_CHAR, AT_STRING, AT_PTR, AT_REFINT,
AT_REFDOUBLE, AT_REFCHAR, AT_CALLBACK, AT_SHORT, AT_BYTE, AT_LONG,
AT_FLOAT};
static const char *const typenames[] =
{"void", "int", "double", "char", "string", "pointer",
"ref int", "ref double", "ref char", "callback",
"short", "byte", "long", "float", NULL};
char *b = alien_checkbuffer(L, 1);
int offset = luaL_checkinteger(L, 2) - 1;
int type = types[luaL_checkoption(L, 4, "char", typenames)];
switch(type) {
case AT_SHORT: *((short*)(&b[offset])) = (short)lua_tointeger(L, 3); break;
case AT_INT: *((int*)(&b[offset])) = (int)lua_tointeger(L, 3); break;
case AT_LONG: *((long*)(&b[offset])) = (long)lua_tointeger(L, 3); break;
case AT_BYTE: b[offset] = (signed char)lua_tointeger(L, 3); break;
case AT_CHAR: b[offset] = (char)lua_tointeger(L, 3); break;
case AT_FLOAT: *((float*)(&b[offset])) = (float)lua_tonumber(L, 3); break;
case AT_DOUBLE: *((double*)(&b[offset])) = (double)lua_tonumber(L, 3); break;
case AT_STRING: *((char**)(&b[offset])) =
(lua_isnil(L, 3) ? NULL : (char*)lua_tostring(L, 3)); break;
case AT_CALLBACK: *((void**)(&b[offset])) = alien_checkcallback(L, 3); break;
case AT_PTR: *((void**)(&b[offset])) =
(lua_isnil(L, 3) ? NULL : (lua_isuserdata(L, 3) ? lua_touserdata(L, 3) :
(void*)lua_tostring(L, 3))); break;
default:
luaL_error(L, "alien: unknown type in buffer:put");
}
return 0;
}