diff options
author | Kim Alvefur <zash@zash.se> | 2019-09-07 13:37:47 +0200 |
---|---|---|
committer | Kim Alvefur <zash@zash.se> | 2019-09-07 13:37:47 +0200 |
commit | 5d87a7d46ffa09262fcc6813b7bc6ce63992abd1 (patch) | |
tree | 9e22f05c2c62cdfb66e6e167c13c4691baefb8d8 | |
parent | 2f28ade873f29404b323a8e9c09e144e5f5457ae (diff) | |
download | prosody-5d87a7d46ffa09262fcc6813b7bc6ce63992abd1.tar.gz prosody-5d87a7d46ffa09262fcc6813b7bc6ce63992abd1.zip |
util.strbitop: Library for bitwise operations on strings
-rw-r--r-- | util-src/GNUmakefile | 2 | ||||
-rw-r--r-- | util-src/makefile | 2 | ||||
-rw-r--r-- | util-src/strbitop.c | 91 |
3 files changed, 93 insertions, 2 deletions
diff --git a/util-src/GNUmakefile b/util-src/GNUmakefile index 054c9201..a8b3529f 100644 --- a/util-src/GNUmakefile +++ b/util-src/GNUmakefile @@ -7,7 +7,7 @@ INSTALL_DATA=install -m644 TARGET?=../util/ ALL=encodings.so hashes.so net.so pposix.so signal.so table.so \ - ringbuffer.so time.so poll.so compat.so + ringbuffer.so time.so poll.so compat.so strbitop.so ifdef RANDOM ALL+=crand.so diff --git a/util-src/makefile b/util-src/makefile index 700633b4..02bad40a 100644 --- a/util-src/makefile +++ b/util-src/makefile @@ -6,7 +6,7 @@ INSTALL_DATA=install -m644 TARGET?=../util/ ALL=encodings.so hashes.so net.so pposix.so signal.so table.so \ - ringbuffer.so time.so poll.so compat.so + ringbuffer.so time.so poll.so compat.so strbitop.so .ifdef $(RANDOM) ALL+=crand.so diff --git a/util-src/strbitop.c b/util-src/strbitop.c new file mode 100644 index 00000000..a26288e5 --- /dev/null +++ b/util-src/strbitop.c @@ -0,0 +1,91 @@ +/* + * This project is MIT licensed. Please see the + * COPYING file in the source package for more information. + * + * Copyright (C) 2016 Kim Alvefur + */ + +#include <lua.h> +#include <lauxlib.h> + +#if (LUA_VERSION_NUM == 501) +#define luaL_setfuncs(L, R, N) luaL_register(L, NULL, R) +#endif + +/* TODO Deduplicate code somehow */ + +int strop_and(lua_State* L) { + luaL_Buffer buf; + size_t a, b, i; + const char* str_a = luaL_checklstring(L, 1, &a); + const char* str_b = luaL_checklstring(L, 2, &b); + + luaL_buffinit(L, &buf); + + if(a == 0 || b == 0) { + lua_settop(L, 1); + return 1; + } + + for(i = 0; i < a; i++) { + luaL_addchar(&buf, str_a[i] & str_b[i % b]); + } + + luaL_pushresult(&buf); + return 1; +} + +int strop_or(lua_State* L) { + luaL_Buffer buf; + size_t a, b, i; + const char* str_a = luaL_checklstring(L, 1, &a); + const char* str_b = luaL_checklstring(L, 2, &b); + + luaL_buffinit(L, &buf); + + if(a == 0 || b == 0) { + lua_settop(L, 1); + return 1; + } + + for(i = 0; i < a; i++) { + luaL_addchar(&buf, str_a[i] | str_b[i % b]); + } + + luaL_pushresult(&buf); + return 1; +} + +int strop_xor(lua_State* L) { + luaL_Buffer buf; + size_t a, b, i; + const char* str_a = luaL_checklstring(L, 1, &a); + const char* str_b = luaL_checklstring(L, 2, &b); + + luaL_buffinit(L, &buf); + + if(a == 0 || b == 0) { + lua_settop(L, 1); + return 1; + } + + for(i = 0; i < a; i++) { + luaL_addchar(&buf, str_a[i] ^ str_b[i % b]); + } + + luaL_pushresult(&buf); + return 1; +} + +LUA_API int luaopen_util_strbitop(lua_State *L) { + luaL_Reg exports[] = { + { "sand", strop_and }, + { "sor", strop_or }, + { "sxor", strop_xor }, + { NULL, NULL } + }; + + lua_newtable(L); + luaL_setfuncs(L, exports, 0); + return 1; +} |