webmcp

annotate libraries/multirand/multirand.c @ 2:72860d232f32

Version 1.0.2

Fixed bug with explicit garbage collection (requests > 256kB caused an error)

Views prefixed with an underscore can't be called externally

ui.paginate now displays the last page, if the selected page number is too high.
author jbe/bsw
date Thu Dec 10 12:00:00 2009 +0100 (2009-12-10)
parents 9fdfb27f8e67
children 3d43a5cf17c1
rev   line source
jbe/bsw@0 1 #include <lua.h>
jbe/bsw@0 2 #include <lauxlib.h>
jbe/bsw@0 3 #include <dirent.h>
jbe/bsw@0 4
jbe/bsw@0 5 static FILE *multirand_dev;
jbe/bsw@0 6
jbe/bsw@0 7 static lua_Integer multirand_range(
jbe/bsw@0 8 lua_State *L, lua_Integer from, lua_Integer to
jbe/bsw@0 9 ) {
jbe/bsw@0 10 lua_Integer range;
jbe/bsw@0 11 int bits = 0;
jbe/bsw@0 12 lua_Integer bit_mask = 0;
jbe/bsw@0 13 if (to < from) return luaL_error(L, "Assertion failed in C.");
jbe/bsw@0 14 range = to - from;
jbe/bsw@0 15 {
jbe/bsw@0 16 lua_Integer tmp;
jbe/bsw@0 17 tmp = range;
jbe/bsw@0 18 while (tmp) {
jbe/bsw@0 19 bits++;
jbe/bsw@0 20 bit_mask <<= 1;
jbe/bsw@0 21 bit_mask |= 1;
jbe/bsw@0 22 tmp >>= 1;
jbe/bsw@0 23 }
jbe/bsw@0 24 }
jbe/bsw@0 25 while (1) {
jbe/bsw@0 26 int i;
jbe/bsw@0 27 lua_Integer rnd = 0;
jbe/bsw@0 28 for (i = 0; i < (bits + 7) / 8; i++) {
jbe/bsw@0 29 int b;
jbe/bsw@0 30 b = getc(multirand_dev);
jbe/bsw@0 31 if (b == EOF) {
jbe/bsw@0 32 return luaL_error(L, "I/O error while reading random.");
jbe/bsw@0 33 }
jbe/bsw@0 34 rnd = (rnd << 8) | (unsigned char)b;
jbe/bsw@0 35 }
jbe/bsw@0 36 rnd &= bit_mask;
jbe/bsw@0 37 if (rnd <= range) return from + rnd;
jbe/bsw@0 38 }
jbe/bsw@0 39 }
jbe/bsw@0 40
jbe/bsw@0 41 static int multirand_integer(lua_State *L) {
jbe/bsw@0 42 lua_Integer arg1, arg2;
jbe/bsw@0 43 lua_settop(L, 2);
jbe/bsw@0 44 arg1 = luaL_checkinteger(L, 1);
jbe/bsw@0 45 if (lua_toboolean(L, 2)) {
jbe/bsw@0 46 arg2 = luaL_optinteger(L, 2, 0);
jbe/bsw@0 47 if (arg1 > arg2) {
jbe/bsw@0 48 return luaL_error(L,
jbe/bsw@0 49 "Upper boundary is smaller than lower boundary."
jbe/bsw@0 50 );
jbe/bsw@0 51 } else if (arg1 == arg2) {
jbe/bsw@0 52 lua_pushinteger(L, arg1);
jbe/bsw@0 53 } else {
jbe/bsw@0 54 lua_pushinteger(L, multirand_range(L, arg1, arg2));
jbe/bsw@0 55 }
jbe/bsw@0 56 } else {
jbe/bsw@0 57 luaL_argcheck(L, arg1 >= 1, 1, "smaller than 1");
jbe/bsw@0 58 lua_pushinteger(L, multirand_range(L, 1, arg1));
jbe/bsw@0 59 }
jbe/bsw@0 60 return 1;
jbe/bsw@0 61 }
jbe/bsw@0 62
jbe/bsw@0 63 static int multirand_fraction(lua_State *L) {
jbe/bsw@0 64 int i, j;
jbe/bsw@0 65 lua_settop(L, 0);
jbe/bsw@0 66 lua_Number rnd = 0.0;
jbe/bsw@0 67 for (i = 0; i < 8; i++) {
jbe/bsw@0 68 int b;
jbe/bsw@0 69 unsigned char c;
jbe/bsw@0 70 b = getc(multirand_dev);
jbe/bsw@0 71 if (b == EOF) return luaL_error(L, "I/O error while reading random.");
jbe/bsw@0 72 c = (unsigned char) b;
jbe/bsw@0 73 for (j = 0; j < 8; j++) {
jbe/bsw@0 74 rnd /= 2.0;
jbe/bsw@0 75 if (c & 1) rnd += 0.5;
jbe/bsw@0 76 c >>= 1;
jbe/bsw@0 77 }
jbe/bsw@0 78 }
jbe/bsw@0 79 lua_pushnumber(L, rnd);
jbe/bsw@0 80 return 1;
jbe/bsw@0 81 }
jbe/bsw@0 82
jbe/bsw@0 83 static int multirand_string(lua_State *L) {
jbe/bsw@0 84 int length;
jbe/bsw@0 85 const char *charset;
jbe/bsw@0 86 size_t charset_size;
jbe/bsw@0 87 luaL_Buffer buf;
jbe/bsw@0 88 lua_settop(L, 2);
jbe/bsw@0 89 length = luaL_checkint(L, 1);
jbe/bsw@0 90 charset = luaL_optlstring(L, 2, "abcdefghijklmnopqrstuvwxyz", &charset_size);
jbe/bsw@0 91 if (charset_size > 32767) {
jbe/bsw@0 92 return luaL_error(L, "Set of chars is too big.");
jbe/bsw@0 93 }
jbe/bsw@0 94 luaL_buffinit(L, &buf);
jbe/bsw@0 95 for (; length > 0; length--) {
jbe/bsw@0 96 luaL_addchar(&buf,
jbe/bsw@0 97 charset[multirand_range(L, 0, (lua_Integer)charset_size - 1)]
jbe/bsw@0 98 );
jbe/bsw@0 99 }
jbe/bsw@0 100 luaL_pushresult(&buf);
jbe/bsw@0 101 return 1;
jbe/bsw@0 102 }
jbe/bsw@0 103
jbe/bsw@0 104 static const struct luaL_Reg multirand_module_functions[] = {
jbe/bsw@0 105 {"integer", multirand_integer},
jbe/bsw@0 106 {"fraction", multirand_fraction},
jbe/bsw@0 107 {"string", multirand_string},
jbe/bsw@0 108 {NULL, NULL}
jbe/bsw@0 109 };
jbe/bsw@0 110
jbe/bsw@0 111 int luaopen_multirand(lua_State *L) {
jbe/bsw@0 112 const char *module_name;
jbe/bsw@0 113 lua_settop(L, 1);
jbe/bsw@0 114 module_name = lua_tostring(L, 1);
jbe/bsw@0 115 if (module_name) {
jbe/bsw@0 116 luaL_register(L, module_name, multirand_module_functions);
jbe/bsw@0 117 } else {
jbe/bsw@0 118 luaL_register(L, "multirand", multirand_module_functions);
jbe/bsw@0 119 }
jbe/bsw@0 120 lua_replace(L, 1);
jbe/bsw@0 121 multirand_dev = fopen("/dev/urandom", "r");
jbe/bsw@0 122 if (!multirand_dev) return luaL_error(L, "Could not open /dev/urandom.");
jbe/bsw@0 123 return 1;
jbe/bsw@0 124 }

Impressum / About Us