aboutsummaryrefslogtreecommitdiffstats
path: root/util-src/strbitop.c
diff options
context:
space:
mode:
Diffstat (limited to 'util-src/strbitop.c')
-rw-r--r--util-src/strbitop.c52
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);
+}