diff options
Diffstat (limited to 'util-src/strbitop.c')
-rw-r--r-- | util-src/strbitop.c | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/util-src/strbitop.c b/util-src/strbitop.c index 89fce661..2f6bf6e6 100644 --- a/util-src/strbitop.c +++ b/util-src/strbitop.c @@ -8,13 +8,12 @@ #include <lua.h> #include <lauxlib.h> -#if (LUA_VERSION_NUM == 501) -#define luaL_setfuncs(L, R, N) luaL_register(L, NULL, R) -#endif +#include <sys/param.h> +#include <limits.h> /* TODO Deduplicate code somehow */ -int strop_and(lua_State *L) { +static int strop_and(lua_State *L) { luaL_Buffer buf; size_t a, b, i; const char *str_a = luaL_checklstring(L, 1, &a); @@ -35,7 +34,7 @@ int strop_and(lua_State *L) { return 1; } -int strop_or(lua_State *L) { +static int strop_or(lua_State *L) { luaL_Buffer buf; size_t a, b, i; const char *str_a = luaL_checklstring(L, 1, &a); @@ -56,7 +55,7 @@ int strop_or(lua_State *L) { return 1; } -int strop_xor(lua_State *L) { +static int strop_xor(lua_State *L) { luaL_Buffer buf; size_t a, b, i; const char *str_a = luaL_checklstring(L, 1, &a); @@ -77,11 +76,46 @@ int strop_xor(lua_State *L) { return 1; } -LUA_API int luaopen_util_strbitop(lua_State *L) { +unsigned int clz(unsigned char c) { +#if __GNUC__ + return __builtin_clz((unsigned int) c) - ((sizeof(int)-1)*CHAR_BIT); +#else + if(c & 0x80) return 0; + if(c & 0x40) return 1; + if(c & 0x20) return 2; + if(c & 0x10) return 3; + if(c & 0x08) return 4; + if(c & 0x04) return 5; + if(c & 0x02) return 6; + if(c & 0x01) return 7; + return 8; +#endif +} + +LUA_API int strop_common_prefix_bits(lua_State *L) { + size_t a, b, i; + const char *str_a = luaL_checklstring(L, 1, &a); + const char *str_b = luaL_checklstring(L, 2, &b); + + size_t min_len = MIN(a, b); + + for(i=0; i<min_len; i++) { + if(str_a[i] != str_b[i]) { + lua_pushinteger(L, i*8 + (clz(str_a[i] ^ str_b[i]))); + return 1; + } + } + + lua_pushinteger(L, i*8); + return 1; +} + +LUA_API int luaopen_prosody_util_strbitop(lua_State *L) { luaL_Reg exports[] = { { "sand", strop_and }, { "sor", strop_or }, { "sxor", strop_xor }, + { "common_prefix_bits", strop_common_prefix_bits }, { NULL, NULL } }; @@ -89,3 +123,7 @@ LUA_API int luaopen_util_strbitop(lua_State *L) { luaL_setfuncs(L, exports, 0); return 1; } + +LUA_API int luaopen_util_strbitop(lua_State *L) { + return luaopen_prosody_util_strbitop(L); +} |