Skip to content

Commit bf3153d

Browse files
committed
added uuid extension
1 parent c492814 commit bf3153d

File tree

5 files changed

+162
-0
lines changed

5 files changed

+162
-0
lines changed

extensions/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ add_library(crypto_mod SHARED
8686
add_library(regex_mod SHARED
8787
regex.c)
8888

89+
add_library(uuid_mod SHARED
90+
uuid.c
91+
deps/uuid4.c)
92+
8993
target_link_libraries(sqlite_mod ${STATIC_LIB_TARGET})
9094
target_link_libraries(curl_mod ${STATIC_LIB_TARGET})
9195
target_link_libraries(redis_mod ${STATIC_LIB_TARGET})
@@ -97,6 +101,7 @@ target_link_libraries(zeromq_mod ${STATIC_LIB_TARGET})
97101
target_link_libraries(leveldb_mod ${STATIC_LIB_TARGET})
98102
target_link_libraries(crypto_mod ${STATIC_LIB_TARGET})
99103
target_link_libraries(regex_mod ${STATIC_LIB_TARGET})
104+
target_link_libraries(uuid_mod ${STATIC_LIB_TARGET})
100105

101106
set_target_properties(sqlite_mod PROPERTIES PREFIX "")
102107
set_target_properties(curl_mod PROPERTIES PREFIX "")
@@ -109,6 +114,7 @@ set_target_properties(zeromq_mod PROPERTIES PREFIX "")
109114
set_target_properties(leveldb_mod PROPERTIES PREFIX "")
110115
set_target_properties(crypto_mod PROPERTIES PREFIX "")
111116
set_target_properties(regex_mod PROPERTIES PREFIX "")
117+
set_target_properties(uuid_mod PROPERTIES PREFIX "")
112118

113119
if(MSVC)
114120
target_link_libraries(sqlite_mod PRIVATE SQLite::SQLite3)

extensions/deps/uuid4.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/**
2+
* Copyright (c) 2018 rxi
3+
*
4+
* This library is free software; you can redistribute it and/or modify it
5+
* under the terms of the MIT license. See LICENSE for details.
6+
*/
7+
8+
#include <stdio.h>
9+
#include <stdint.h>
10+
11+
#if defined(_WIN32)
12+
#include <windows.h>
13+
#include <wincrypt.h>
14+
#endif
15+
16+
#include "uuid4.h"
17+
18+
19+
static uint64_t seed[2];
20+
21+
22+
static uint64_t xorshift128plus(uint64_t *s) {
23+
/* http://xorshift.di.unimi.it/xorshift128plus.c */
24+
uint64_t s1 = s[0];
25+
const uint64_t s0 = s[1];
26+
s[0] = s0;
27+
s1 ^= s1 << 23;
28+
s[1] = s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5);
29+
return s[1] + s0;
30+
}
31+
32+
33+
int uuid4_init(void) {
34+
#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
35+
int res;
36+
FILE *fp = fopen("/dev/urandom", "rb");
37+
if (!fp) {
38+
return UUID4_EFAILURE;
39+
}
40+
res = fread(seed, 1, sizeof(seed), fp);
41+
fclose(fp);
42+
if ( res != sizeof(seed) ) {
43+
return UUID4_EFAILURE;
44+
}
45+
46+
#elif defined(_WIN32)
47+
int res;
48+
HCRYPTPROV hCryptProv;
49+
res = CryptAcquireContext(
50+
&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
51+
if (!res) {
52+
return UUID4_EFAILURE;
53+
}
54+
res = CryptGenRandom(hCryptProv, (DWORD) sizeof(seed), (PBYTE) seed);
55+
CryptReleaseContext(hCryptProv, 0);
56+
if (!res) {
57+
return UUID4_EFAILURE;
58+
}
59+
60+
#else
61+
#error "unsupported platform"
62+
#endif
63+
return UUID4_ESUCCESS;
64+
}
65+
66+
67+
void uuid4_generate(char *dst) {
68+
static const char *template = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
69+
static const char *chars = "0123456789abcdef";
70+
union { unsigned char b[16]; uint64_t word[2]; } s;
71+
const char *p;
72+
int i, n;
73+
/* get random */
74+
s.word[0] = xorshift128plus(seed);
75+
s.word[1] = xorshift128plus(seed);
76+
/* build string */
77+
p = template;
78+
i = 0;
79+
while (*p) {
80+
n = s.b[i >> 1];
81+
n = (i & 1) ? (n >> 4) : (n & 0xf);
82+
switch (*p) {
83+
case 'x' : *dst = chars[n]; i++; break;
84+
case 'y' : *dst = chars[(n & 0x3) + 8]; i++; break;
85+
default : *dst = *p;
86+
}
87+
dst++, p++;
88+
}
89+
*dst = '\0';
90+
}

extensions/deps/uuid4.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Copyright (c) 2018 rxi
3+
*
4+
* This library is free software; you can redistribute it and/or modify it
5+
* under the terms of the MIT license. See LICENSE for details.
6+
*/
7+
8+
#ifndef UUID4_H
9+
#define UUID4_H
10+
11+
#define UUID4_VERSION "1.0.0"
12+
#define UUID4_LEN 37
13+
14+
enum {
15+
UUID4_ESUCCESS = 0,
16+
UUID4_EFAILURE = -1
17+
};
18+
19+
int uuid4_init(void);
20+
void uuid4_generate(char *dst);
21+
22+
#endif

extensions/uuid.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//
2+
// The Hook Programming Language
3+
// uuid.c
4+
//
5+
6+
#include "uuid.h"
7+
#include "deps/uuid4.h"
8+
9+
static void random_call(HkState *state, HkValue *args);
10+
11+
static void random_call(HkState *state, HkValue *args)
12+
{
13+
(void) args;
14+
HkString *str = hk_string_new_with_capacity(UUID4_LEN);
15+
uuid4_init();
16+
uuid4_generate(str->chars);
17+
str->length = UUID4_LEN;
18+
str->chars[str->length] = '\0';
19+
hk_state_push_string(state, str);
20+
}
21+
22+
HK_LOAD_MODULE_HANDLER(uuid)
23+
{
24+
hk_state_push_string_from_chars(state, -1, "uuid");
25+
hk_return_if_not_ok(state);
26+
hk_state_push_string_from_chars(state, -1, "random");
27+
hk_return_if_not_ok(state);
28+
hk_state_push_new_native(state, "random", 0, random_call);
29+
hk_return_if_not_ok(state);
30+
hk_state_construct(state, 1);
31+
}

extensions/uuid.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//
2+
// The Hook Programming Language
3+
// uuid.h
4+
//
5+
6+
#ifndef UUID_H
7+
#define UUID_H
8+
9+
#include <hook.h>
10+
11+
HK_LOAD_MODULE_HANDLER(uuid);
12+
13+
#endif // UUID_H

0 commit comments

Comments
 (0)