#include "common/c_converter.h"
#include "common/c_content.h"
#include "log.h"
+#include "porting.h"
+#include "util/numeric.h"
-// garbage collector
-int LuaPerlinNoise::gc_object(lua_State *L)
+///////////////////////////////////////
+/*
+ LuaPerlinNoise
+*/
+
+LuaPerlinNoise::LuaPerlinNoise(NoiseParams *params) :
+ np(*params)
+{
+}
+
+
+LuaPerlinNoise::~LuaPerlinNoise()
{
- LuaPerlinNoise *o = *(LuaPerlinNoise **)(lua_touserdata(L, 1));
- delete o;
- return 0;
}
+
int LuaPerlinNoise::l_get2d(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
LuaPerlinNoise *o = checkobject(L, 1);
- v2f pos2d = read_v2f(L,2);
- lua_Number val = noise2d_perlin(pos2d.X/o->scale, pos2d.Y/o->scale, o->seed, o->octaves, o->persistence);
+ v2f p = check_v2f(L, 2);
+ lua_Number val = NoisePerlin2D(&o->np, p.X, p.Y, 0);
lua_pushnumber(L, val);
return 1;
}
+
+
int LuaPerlinNoise::l_get3d(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
LuaPerlinNoise *o = checkobject(L, 1);
- v3f pos3d = read_v3f(L,2);
- lua_Number val = noise3d_perlin(pos3d.X/o->scale, pos3d.Y/o->scale, pos3d.Z/o->scale, o->seed, o->octaves, o->persistence);
+ v3f p = check_v3f(L, 2);
+ lua_Number val = NoisePerlin3D(&o->np, p.X, p.Y, p.Z, 0);
lua_pushnumber(L, val);
return 1;
}
-LuaPerlinNoise::LuaPerlinNoise(int a_seed, int a_octaves, float a_persistence,
- float a_scale):
- seed(a_seed),
- octaves(a_octaves),
- persistence(a_persistence),
- scale(a_scale)
-{
-}
-
-LuaPerlinNoise::~LuaPerlinNoise()
-{
-}
-
-// LuaPerlinNoise(seed, octaves, persistence, scale)
-// Creates an LuaPerlinNoise and leaves it on top of stack
int LuaPerlinNoise::create_object(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
- int seed = luaL_checkint(L, 1);
- int octaves = luaL_checkint(L, 2);
- float persistence = luaL_checknumber(L, 3);
- float scale = luaL_checknumber(L, 4);
- LuaPerlinNoise *o = new LuaPerlinNoise(seed, octaves, persistence, scale);
+
+ NoiseParams params;
+
+ if (lua_istable(L, 1)) {
+ read_noiseparams(L, 1, ¶ms);
+ } else {
+ params.seed = luaL_checkint(L, 1);
+ params.octaves = luaL_checkint(L, 2);
+ params.persist = luaL_checknumber(L, 3);
+ params.spread = v3f(1, 1, 1) * luaL_checknumber(L, 4);
+ }
+
+ LuaPerlinNoise *o = new LuaPerlinNoise(¶ms);
+
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
luaL_getmetatable(L, className);
lua_setmetatable(L, -2);
return 1;
}
-LuaPerlinNoise* LuaPerlinNoise::checkobject(lua_State *L, int narg)
+
+int LuaPerlinNoise::gc_object(lua_State *L)
+{
+ LuaPerlinNoise *o = *(LuaPerlinNoise **)(lua_touserdata(L, 1));
+ delete o;
+ return 0;
+}
+
+
+LuaPerlinNoise *LuaPerlinNoise::checkobject(lua_State *L, int narg)
{
NO_MAP_LOCK_REQUIRED;
luaL_checktype(L, narg, LUA_TUSERDATA);
void *ud = luaL_checkudata(L, narg, className);
- if(!ud) luaL_typerror(L, narg, className);
- return *(LuaPerlinNoise**)ud; // unbox pointer
+ if (!ud)
+ luaL_typerror(L, narg, className);
+ return *(LuaPerlinNoise **)ud;
}
+
void LuaPerlinNoise::Register(lua_State *L)
{
lua_newtable(L);
lua_pushliteral(L, "__metatable");
lua_pushvalue(L, methodtable);
- lua_settable(L, metatable); // hide metatable from Lua getmetatable()
+ lua_settable(L, metatable);
lua_pushliteral(L, "__index");
lua_pushvalue(L, methodtable);
lua_pushcfunction(L, gc_object);
lua_settable(L, metatable);
- lua_pop(L, 1); // drop metatable
+ lua_pop(L, 1);
- luaL_openlib(L, 0, methods, 0); // fill methodtable
- lua_pop(L, 1); // drop methodtable
+ luaL_openlib(L, 0, methods, 0);
+ lua_pop(L, 1);
- // Can be created from Lua (PerlinNoise(seed, octaves, persistence)
lua_register(L, className, create_object);
}
+
const char LuaPerlinNoise::className[] = "PerlinNoise";
const luaL_reg LuaPerlinNoise::methods[] = {
luamethod(LuaPerlinNoise, get2d),
{0,0}
};
+///////////////////////////////////////
/*
- PerlinNoiseMap
- */
+ LuaPerlinNoiseMap
+*/
+
+LuaPerlinNoiseMap::LuaPerlinNoiseMap(NoiseParams *params, s32 seed, v3s16 size)
+{
+ m_is3d = size.Z > 1;
+ np = *params;
+ try {
+ noise = new Noise(&np, seed, size.X, size.Y, size.Z);
+ } catch (InvalidNoiseParamsException &e) {
+ throw LuaError(e.what());
+ }
+}
-int LuaPerlinNoiseMap::gc_object(lua_State *L)
+LuaPerlinNoiseMap::~LuaPerlinNoiseMap()
{
- LuaPerlinNoiseMap *o = *(LuaPerlinNoiseMap **)(lua_touserdata(L, 1));
- delete o;
- return 0;
+ delete noise;
}
+
int LuaPerlinNoiseMap::l_get2dMap(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
- int i = 0;
+ size_t i = 0;
LuaPerlinNoiseMap *o = checkobject(L, 1);
- v2f p = read_v2f(L, 2);
+ v2f p = check_v2f(L, 2);
Noise *n = o->noise;
n->perlinMap2D(p.X, p.Y);
lua_newtable(L);
- for (int y = 0; y != n->sy; y++) {
+ for (u32 y = 0; y != n->sy; y++) {
lua_newtable(L);
- for (int x = 0; x != n->sx; x++) {
- float noiseval = n->np->offset + n->np->scale * n->result[i++];
- lua_pushnumber(L, noiseval);
+ for (u32 x = 0; x != n->sx; x++) {
+ lua_pushnumber(L, n->result[i++]);
lua_rawseti(L, -2, x + 1);
}
lua_rawseti(L, -2, y + 1);
return 1;
}
+
int LuaPerlinNoiseMap::l_get2dMap_flat(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
LuaPerlinNoiseMap *o = checkobject(L, 1);
- v2f p = read_v2f(L, 2);
+ v2f p = check_v2f(L, 2);
+ bool use_buffer = lua_istable(L, 3);
Noise *n = o->noise;
n->perlinMap2D(p.X, p.Y);
- int maplen = n->sx * n->sy;
-
- lua_newtable(L);
- for (int i = 0; i != maplen; i++) {
- float noiseval = n->np->offset + n->np->scale * n->result[i];
- lua_pushnumber(L, noiseval);
+ size_t maplen = n->sx * n->sy;
+
+ if (use_buffer)
+ lua_pushvalue(L, 3);
+ else
+ lua_newtable(L);
+
+ for (size_t i = 0; i != maplen; i++) {
+ lua_pushnumber(L, n->result[i]);
lua_rawseti(L, -2, i + 1);
}
return 1;
}
+
int LuaPerlinNoiseMap::l_get3dMap(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
- int i = 0;
+ size_t i = 0;
LuaPerlinNoiseMap *o = checkobject(L, 1);
- v3f p = read_v3f(L, 2);
+ v3f p = check_v3f(L, 2);
+
+ if (!o->m_is3d)
+ return 0;
Noise *n = o->noise;
n->perlinMap3D(p.X, p.Y, p.Z);
lua_newtable(L);
- for (int z = 0; z != n->sz; z++) {
+ for (u32 z = 0; z != n->sz; z++) {
lua_newtable(L);
- for (int y = 0; y != n->sy; y++) {
+ for (u32 y = 0; y != n->sy; y++) {
lua_newtable(L);
- for (int x = 0; x != n->sx; x++) {
- lua_pushnumber(L, n->np->offset + n->np->scale * n->result[i++]);
+ for (u32 x = 0; x != n->sx; x++) {
+ lua_pushnumber(L, n->result[i++]);
lua_rawseti(L, -2, x + 1);
}
lua_rawseti(L, -2, y + 1);
return 1;
}
+
int LuaPerlinNoiseMap::l_get3dMap_flat(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
LuaPerlinNoiseMap *o = checkobject(L, 1);
- v3f p = read_v3f(L, 2);
+ v3f p = check_v3f(L, 2);
+ bool use_buffer = lua_istable(L, 3);
+
+ if (!o->m_is3d)
+ return 0;
Noise *n = o->noise;
n->perlinMap3D(p.X, p.Y, p.Z);
+ size_t maplen = n->sx * n->sy * n->sz;
- int maplen = n->sx * n->sy * n->sz;
-
- lua_newtable(L);
- for (int i = 0; i != maplen; i++) {
- float noiseval = n->np->offset + n->np->scale * n->result[i];
- lua_pushnumber(L, noiseval);
+ if (use_buffer)
+ lua_pushvalue(L, 3);
+ else
+ lua_newtable(L);
+
+ for (size_t i = 0; i != maplen; i++) {
+ lua_pushnumber(L, n->result[i]);
lua_rawseti(L, -2, i + 1);
}
return 1;
}
-LuaPerlinNoiseMap::LuaPerlinNoiseMap(NoiseParams *np, int seed, v3s16 size) {
- noise = new Noise(np, seed, size.X, size.Y, size.Z);
+
+int LuaPerlinNoiseMap::l_calc2dMap(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+
+ LuaPerlinNoiseMap *o = checkobject(L, 1);
+ v2f p = check_v2f(L, 2);
+
+ Noise *n = o->noise;
+ n->perlinMap2D(p.X, p.Y);
+
+ return 0;
+}
+
+int LuaPerlinNoiseMap::l_calc3dMap(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+
+ LuaPerlinNoiseMap *o = checkobject(L, 1);
+ v3f p = check_v3f(L, 2);
+
+ if (!o->m_is3d)
+ return 0;
+
+ Noise *n = o->noise;
+ n->perlinMap3D(p.X, p.Y, p.Z);
+
+ return 0;
}
-LuaPerlinNoiseMap::~LuaPerlinNoiseMap()
+
+int LuaPerlinNoiseMap::l_getMapSlice(lua_State *L)
{
- delete noise->np;
- delete noise;
+ NO_MAP_LOCK_REQUIRED;
+
+ LuaPerlinNoiseMap *o = checkobject(L, 1);
+ v3s16 slice_offset = read_v3s16(L, 2);
+ v3s16 slice_size = read_v3s16(L, 3);
+ bool use_buffer = lua_istable(L, 4);
+
+ Noise *n = o->noise;
+
+ if (use_buffer)
+ lua_pushvalue(L, 3);
+ else
+ lua_newtable(L);
+
+ write_array_slice_float(L, lua_gettop(L), n->result,
+ v3u16(n->sx, n->sy, n->sz),
+ v3u16(slice_offset.X, slice_offset.Y, slice_offset.Z),
+ v3u16(slice_size.X, slice_size.Y, slice_size.Z));
+
+ return 1;
}
-// LuaPerlinNoiseMap(np, size)
-// Creates an LuaPerlinNoiseMap and leaves it on top of stack
+
int LuaPerlinNoiseMap::create_object(lua_State *L)
{
- NoiseParams *np = read_noiseparams(L, 1);
- if (!np)
+ NoiseParams np;
+ if (!read_noiseparams(L, 1, &np))
return 0;
v3s16 size = read_v3s16(L, 2);
- LuaPerlinNoiseMap *o = new LuaPerlinNoiseMap(np, 0, size);
+ LuaPerlinNoiseMap *o = new LuaPerlinNoiseMap(&np, 0, size);
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
luaL_getmetatable(L, className);
lua_setmetatable(L, -2);
return 1;
}
-LuaPerlinNoiseMap* LuaPerlinNoiseMap::checkobject(lua_State *L, int narg)
+
+int LuaPerlinNoiseMap::gc_object(lua_State *L)
+{
+ LuaPerlinNoiseMap *o = *(LuaPerlinNoiseMap **)(lua_touserdata(L, 1));
+ delete o;
+ return 0;
+}
+
+
+LuaPerlinNoiseMap *LuaPerlinNoiseMap::checkobject(lua_State *L, int narg)
{
luaL_checktype(L, narg, LUA_TUSERDATA);
if (!ud)
luaL_typerror(L, narg, className);
- return *(LuaPerlinNoiseMap **)ud; // unbox pointer
+ return *(LuaPerlinNoiseMap **)ud;
}
+
void LuaPerlinNoiseMap::Register(lua_State *L)
{
lua_newtable(L);
lua_pushliteral(L, "__metatable");
lua_pushvalue(L, methodtable);
- lua_settable(L, metatable); // hide metatable from Lua getmetatable()
+ lua_settable(L, metatable);
lua_pushliteral(L, "__index");
lua_pushvalue(L, methodtable);
lua_pushcfunction(L, gc_object);
lua_settable(L, metatable);
- lua_pop(L, 1); // drop metatable
+ lua_pop(L, 1);
- luaL_openlib(L, 0, methods, 0); // fill methodtable
- lua_pop(L, 1); // drop methodtable
+ luaL_openlib(L, 0, methods, 0);
+ lua_pop(L, 1);
- // Can be created from Lua (PerlinNoiseMap(np, size)
lua_register(L, className, create_object);
}
+
const char LuaPerlinNoiseMap::className[] = "PerlinNoiseMap";
const luaL_reg LuaPerlinNoiseMap::methods[] = {
luamethod(LuaPerlinNoiseMap, get2dMap),
luamethod(LuaPerlinNoiseMap, get2dMap_flat),
+ luamethod(LuaPerlinNoiseMap, calc2dMap),
luamethod(LuaPerlinNoiseMap, get3dMap),
luamethod(LuaPerlinNoiseMap, get3dMap_flat),
+ luamethod(LuaPerlinNoiseMap, calc3dMap),
+ luamethod(LuaPerlinNoiseMap, getMapSlice),
{0,0}
};
+///////////////////////////////////////
/*
LuaPseudoRandom
*/
-// garbage collector
-int LuaPseudoRandom::gc_object(lua_State *L)
-{
- LuaPseudoRandom *o = *(LuaPseudoRandom **)(lua_touserdata(L, 1));
- delete o;
- return 0;
-}
-
-// next(self, min=0, max=32767) -> get next value
int LuaPseudoRandom::l_next(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
+
LuaPseudoRandom *o = checkobject(L, 1);
int min = 0;
int max = 32767;
- lua_settop(L, 3); // Fill 2 and 3 with nil if they don't exist
- if(!lua_isnil(L, 2))
+ lua_settop(L, 3);
+ if (lua_isnumber(L, 2))
min = luaL_checkinteger(L, 2);
- if(!lua_isnil(L, 3))
+ if (lua_isnumber(L, 3))
max = luaL_checkinteger(L, 3);
- if(max < min){
+ if (max < min) {
errorstream<<"PseudoRandom.next(): max="<<max<<" min="<<min<<std::endl;
- throw LuaError(L, "PseudoRandom.next(): max < min");
+ throw LuaError("PseudoRandom.next(): max < min");
}
if(max - min != 32767 && max - min > 32767/5)
- throw LuaError(L, "PseudoRandom.next() max-min is not 32767"
+ throw LuaError("PseudoRandom.next() max-min is not 32767"
" and is > 32768/5. This is disallowed due to"
" the bad random distribution the"
" implementation would otherwise make.");
}
-LuaPseudoRandom::LuaPseudoRandom(int seed):
- m_pseudo(seed)
+int LuaPseudoRandom::create_object(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+
+ u64 seed = luaL_checknumber(L, 1);
+ LuaPseudoRandom *o = new LuaPseudoRandom(seed);
+ *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+ luaL_getmetatable(L, className);
+ lua_setmetatable(L, -2);
+ return 1;
+}
+
+
+int LuaPseudoRandom::gc_object(lua_State *L)
+{
+ LuaPseudoRandom *o = *(LuaPseudoRandom **)(lua_touserdata(L, 1));
+ delete o;
+ return 0;
+}
+
+
+LuaPseudoRandom *LuaPseudoRandom::checkobject(lua_State *L, int narg)
+{
+ luaL_checktype(L, narg, LUA_TUSERDATA);
+ void *ud = luaL_checkudata(L, narg, className);
+ if (!ud)
+ luaL_typerror(L, narg, className);
+ return *(LuaPseudoRandom **)ud;
+}
+
+
+void LuaPseudoRandom::Register(lua_State *L)
+{
+ lua_newtable(L);
+ int methodtable = lua_gettop(L);
+ luaL_newmetatable(L, className);
+ int metatable = lua_gettop(L);
+
+ lua_pushliteral(L, "__metatable");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__index");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__gc");
+ lua_pushcfunction(L, gc_object);
+ lua_settable(L, metatable);
+
+ lua_pop(L, 1);
+
+ luaL_openlib(L, 0, methods, 0);
+ lua_pop(L, 1);
+
+ lua_register(L, className, create_object);
+}
+
+
+const char LuaPseudoRandom::className[] = "PseudoRandom";
+const luaL_reg LuaPseudoRandom::methods[] = {
+ luamethod(LuaPseudoRandom, next),
+ {0,0}
+};
+
+///////////////////////////////////////
+/*
+ LuaPcgRandom
+*/
+
+int LuaPcgRandom::l_next(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+
+ LuaPcgRandom *o = checkobject(L, 1);
+ u32 min = lua_isnumber(L, 2) ? lua_tointeger(L, 2) : o->m_rnd.RANDOM_MIN;
+ u32 max = lua_isnumber(L, 3) ? lua_tointeger(L, 3) : o->m_rnd.RANDOM_MAX;
+
+ lua_pushinteger(L, o->m_rnd.range(min, max));
+ return 1;
+}
+
+
+int LuaPcgRandom::l_rand_normal_dist(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+
+ LuaPcgRandom *o = checkobject(L, 1);
+ u32 min = lua_isnumber(L, 2) ? lua_tointeger(L, 2) : o->m_rnd.RANDOM_MIN;
+ u32 max = lua_isnumber(L, 3) ? lua_tointeger(L, 3) : o->m_rnd.RANDOM_MAX;
+ int num_trials = lua_isnumber(L, 4) ? lua_tointeger(L, 4) : 6;
+
+ lua_pushinteger(L, o->m_rnd.randNormalDist(min, max, num_trials));
+ return 1;
+}
+
+
+int LuaPcgRandom::create_object(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+
+ u64 seed = luaL_checknumber(L, 1);
+ LuaPcgRandom *o = lua_isnumber(L, 2) ?
+ new LuaPcgRandom(seed, lua_tointeger(L, 2)) :
+ new LuaPcgRandom(seed);
+ *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+ luaL_getmetatable(L, className);
+ lua_setmetatable(L, -2);
+ return 1;
+}
+
+
+int LuaPcgRandom::gc_object(lua_State *L)
+{
+ LuaPcgRandom *o = *(LuaPcgRandom **)(lua_touserdata(L, 1));
+ delete o;
+ return 0;
+}
+
+
+LuaPcgRandom *LuaPcgRandom::checkobject(lua_State *L, int narg)
{
+ luaL_checktype(L, narg, LUA_TUSERDATA);
+ void *ud = luaL_checkudata(L, narg, className);
+ if (!ud)
+ luaL_typerror(L, narg, className);
+ return *(LuaPcgRandom **)ud;
}
-LuaPseudoRandom::~LuaPseudoRandom()
+
+void LuaPcgRandom::Register(lua_State *L)
{
+ lua_newtable(L);
+ int methodtable = lua_gettop(L);
+ luaL_newmetatable(L, className);
+ int metatable = lua_gettop(L);
+
+ lua_pushliteral(L, "__metatable");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__index");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__gc");
+ lua_pushcfunction(L, gc_object);
+ lua_settable(L, metatable);
+
+ lua_pop(L, 1);
+
+ luaL_openlib(L, 0, methods, 0);
+ lua_pop(L, 1);
+
+ lua_register(L, className, create_object);
}
-const PseudoRandom& LuaPseudoRandom::getItem() const
+
+const char LuaPcgRandom::className[] = "PcgRandom";
+const luaL_reg LuaPcgRandom::methods[] = {
+ luamethod(LuaPcgRandom, next),
+ luamethod(LuaPcgRandom, rand_normal_dist),
+ {0,0}
+};
+
+///////////////////////////////////////
+/*
+ LuaSecureRandom
+*/
+
+bool LuaSecureRandom::fillRandBuf()
{
- return m_pseudo;
+ return porting::secure_rand_fill_buf(m_rand_buf, RAND_BUF_SIZE);
}
-PseudoRandom& LuaPseudoRandom::getItem()
+
+int LuaSecureRandom::l_next_bytes(lua_State *L)
{
- return m_pseudo;
+ NO_MAP_LOCK_REQUIRED;
+
+ LuaSecureRandom *o = checkobject(L, 1);
+ u32 count = lua_isnumber(L, 2) ? lua_tointeger(L, 2) : 1;
+
+ // Limit count
+ count = MYMIN(RAND_BUF_SIZE, count);
+
+ // Find out whether we can pass directly from our array, or have to do some gluing
+ size_t count_remaining = RAND_BUF_SIZE - o->m_rand_idx;
+ if (count_remaining >= count) {
+ lua_pushlstring(L, o->m_rand_buf + o->m_rand_idx, count);
+ o->m_rand_idx += count;
+ } else {
+ char output_buf[RAND_BUF_SIZE];
+
+ // Copy over with what we have left from our current buffer
+ memcpy(output_buf, o->m_rand_buf + o->m_rand_idx, count_remaining);
+
+ // Refill buffer and copy over the remainder of what was requested
+ o->fillRandBuf();
+ memcpy(output_buf + count_remaining, o->m_rand_buf, count - count_remaining);
+
+ // Update index
+ o->m_rand_idx = count - count_remaining;
+
+ lua_pushlstring(L, output_buf, count);
+ }
+
+ return 1;
}
-// LuaPseudoRandom(seed)
-// Creates an LuaPseudoRandom and leaves it on top of stack
-int LuaPseudoRandom::create_object(lua_State *L)
+
+int LuaSecureRandom::create_object(lua_State *L)
{
- int seed = luaL_checknumber(L, 1);
- LuaPseudoRandom *o = new LuaPseudoRandom(seed);
+ LuaSecureRandom *o = new LuaSecureRandom();
+
+ // Fail and return nil if we can't securely fill the buffer
+ if (!o->fillRandBuf()) {
+ delete o;
+ return 0;
+ }
+
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
luaL_getmetatable(L, className);
lua_setmetatable(L, -2);
return 1;
}
-LuaPseudoRandom* LuaPseudoRandom::checkobject(lua_State *L, int narg)
+
+int LuaSecureRandom::gc_object(lua_State *L)
+{
+ LuaSecureRandom *o = *(LuaSecureRandom **)(lua_touserdata(L, 1));
+ delete o;
+ return 0;
+}
+
+
+LuaSecureRandom *LuaSecureRandom::checkobject(lua_State *L, int narg)
{
luaL_checktype(L, narg, LUA_TUSERDATA);
void *ud = luaL_checkudata(L, narg, className);
- if(!ud) luaL_typerror(L, narg, className);
- return *(LuaPseudoRandom**)ud; // unbox pointer
+ if (!ud)
+ luaL_typerror(L, narg, className);
+ return *(LuaSecureRandom **)ud;
}
-void LuaPseudoRandom::Register(lua_State *L)
+
+void LuaSecureRandom::Register(lua_State *L)
{
lua_newtable(L);
int methodtable = lua_gettop(L);
lua_pushliteral(L, "__metatable");
lua_pushvalue(L, methodtable);
- lua_settable(L, metatable); // hide metatable from Lua getmetatable()
+ lua_settable(L, metatable);
lua_pushliteral(L, "__index");
lua_pushvalue(L, methodtable);
lua_pushcfunction(L, gc_object);
lua_settable(L, metatable);
- lua_pop(L, 1); // drop metatable
+ lua_pop(L, 1);
- luaL_openlib(L, 0, methods, 0); // fill methodtable
- lua_pop(L, 1); // drop methodtable
+ luaL_openlib(L, 0, methods, 0);
+ lua_pop(L, 1);
- // Can be created from Lua (LuaPseudoRandom(seed))
lua_register(L, className, create_object);
}
-const char LuaPseudoRandom::className[] = "PseudoRandom";
-const luaL_reg LuaPseudoRandom::methods[] = {
- luamethod(LuaPseudoRandom, next),
+const char LuaSecureRandom::className[] = "SecureRandom";
+const luaL_reg LuaSecureRandom::methods[] = {
+ luamethod(LuaSecureRandom, next_bytes),
{0,0}
};