From a121cef86fcf7b3f4e3a8f067a68795da14de72c Mon Sep 17 00:00:00 2001 From: Laria Carolin Chabowski Date: Tue, 2 Apr 2019 21:43:25 +0200 Subject: Expose additional libuuid functions --- lua_uuid.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++-- test/lua_uuid_test.lua | 25 +++++++++++--- 2 files changed, 110 insertions(+), 7 deletions(-) diff --git a/lua_uuid.c b/lua_uuid.c index 94d76b1..60f779c 100644 --- a/lua_uuid.c +++ b/lua_uuid.c @@ -4,11 +4,14 @@ Utility for generating UUIDs by wrapping libuuid's generate(). @license MIT @module lua_uuid */ +#include #include #include #include -/// Generate a UUID +#define UUID_LEN 16 + +/// Generate a UUID. As a shortcut, you can also call the module directly to generate a uuid. // @return uuid_str // @function generate() static int generate(lua_State *L) { @@ -22,7 +25,92 @@ static int generate(lua_State *L) { return 1; } +/// Generate a binary UUID +// @return uuid +// @function generate_binary() +static int generate_binary(lua_State *L) { + uuid_t uuid; + uuid_generate(uuid); + + lua_pushlstring(L, (char *)&uuid, UUID_LEN); + return 1; +} + +/// Unparse UUID (create a hex string representation from a binary string representation) +// @tparam string binary_uuid +// @treturn string uuid_str +// @error if the binary_uuid could not be unparsed +// @function unparse +static int unparse(lua_State *L) { + const char *binary_uuid; + size_t binary_uuid_len; + uuid_t uuid; + char uuid_str[37]; + + binary_uuid = luaL_checklstring(L, 1, &binary_uuid_len); + + if (binary_uuid_len != UUID_LEN) { + lua_pushnil(L); + lua_pushfstring(L, "could not unparse uuid: string length was != %d", UUID_LEN); + return 2; + } + + memcpy(&uuid[0], binary_uuid, UUID_LEN); + + uuid_unparse_lower(uuid, uuid_str); + + lua_pushstring(L, uuid_str); + return 1; +} + +/// Parse a hexadecimal UUID into a binary representation +// @tparam string uuid_str +// @treturn string uuid +// @error if the uuid_str could not be parsed +// @function parse +static int parse(lua_State *L) { + const char *uuid_str; + uuid_t uuid; + + uuid_str = luaL_checkstring(L, 1); + + if (uuid_parse(uuid_str, uuid) != 0) { + lua_pushnil(L); + lua_pushstring(L, "could not parse uuid"); + return 2; + } + + lua_pushlstring(L, (char *)uuid, UUID_LEN); + return 1; +} + +static int mt_call(lua_State *L) { + lua_pop(L, 1); + return generate(L); +} + +static const struct luaL_Reg mylib [] = { + {"generate", generate}, + {"generate_binary", generate_binary}, + {"unparse", unparse}, + {"parse", parse}, + {NULL, NULL} +}; + int luaopen_lua_uuid(lua_State *L) { - lua_pushcfunction(L, generate); + // Set up library table + lua_newtable(L); + const luaL_Reg *fundef = mylib; + for(fundef = mylib; fundef->name != NULL; fundef++) { + lua_pushcfunction(L, fundef->func); + lua_setfield(L, -2, fundef->name); + } + + // Set up metatable + lua_newtable(L); + lua_pushcfunction(L, mt_call); + lua_setfield(L, -2, "__call"); + + lua_setmetatable(L, -2); return 1; } diff --git a/test/lua_uuid_test.lua b/test/lua_uuid_test.lua index 19ebf67..3406d56 100755 --- a/test/lua_uuid_test.lua +++ b/test/lua_uuid_test.lua @@ -2,10 +2,25 @@ package.path = package.path..";./?.lua" local uuid = require "lua_uuid" -assert(type(uuid) == "function") +assert(type(uuid) == "table") -local first = uuid() -local second = uuid() +local function test_generator(gen) + local first = gen() + local second = gen() -assert(first ~= second) -assert(type(uuid()) == "string") + assert(first ~= second) + assert(type(gen()) == "string") +end + +test_generator(uuid) +test_generator(uuid.generate) +test_generator(uuid.generate_binary) + +local hexuuid = "cf08a9b2-3492-4b71-9bd9-eb12d9f463a6" +local binuuid = "\207\008\169\178\052\146\075\113\155\217\235\018\217\244\099\166" + +assert(assert(uuid.parse(hexuuid)) == binuuid) +assert(assert(uuid.unparse(binuuid)) == hexuuid) + +assert(uuid.parse("foobar") == nil) +assert(uuid.unparse("foobar") == nil) -- cgit v1.2.3-54-g00ecf