// Generated by Bux C Backend v2 #include #include #include #include #include typedef const char* String; typedef unsigned char uint8; typedef unsigned short uint16; typedef unsigned int uint32; typedef unsigned long long uint64; typedef signed char int8; typedef short int16; typedef long long int64; typedef float float32; typedef double float64; typedef char char8; void* bux_alloc(unsigned int size); void bux_free(void* ptr); typedef struct TaskHandle TaskHandle; typedef struct Mutex Mutex; typedef struct RwLock RwLock; typedef struct JsonValue JsonValue; typedef struct JsonParser JsonParser; typedef struct StringBuilder StringBuilder; typedef struct Channel_int Channel_int; typedef struct Channel_float64 Channel_float64; typedef enum { Result_Ok, Result_Err } Result_Tag; typedef union { int Ok_0; String Err_0; } Result_Data; typedef struct { Result_Tag tag; Result_Data data; } Result; typedef enum { Option_Some, Option_None } Option_Tag; typedef union { int Some_0; } Option_Data; typedef struct { Option_Tag tag; Option_Data data; } Option; typedef enum { JwtAlg_HS256, JwtAlg_HS384, JwtAlg_HS512, JwtAlg_RS256, JwtAlg_RS384, JwtAlg_RS512, JwtAlg_ES256, JwtAlg_ES384, JwtAlg_EdDSA } JwtAlg_Tag; typedef struct { JwtAlg_Tag tag; } JwtAlg; #define JsonTagNull 0 #define JsonTagBool 1 #define JsonTagNumber 2 #define JsonTagString 3 #define JsonTagArray 4 #define JsonTagObject 5 #define AES_KEY_SIZE 32 #define AES_IV_SIZE 16 #define AES_GCM_TAG_SIZE 16 #define ED25519_PUBKEY_SIZE 32 #define ED25519_PRIVKEY_SIZE 32 #define ED25519_SIG_SIZE 64 struct TaskHandle { void* handle; }; struct Mutex { void* handle; }; struct RwLock { void* handle; }; struct JsonValue { int tag; bool boolVal; float64 numVal; String strVal; JsonValue* arrData; uint arrLen; uint arrCap; String* objKeys; JsonValue* objValues; uint objLen; uint objCap; }; struct JsonParser { String src; uint pos; uint len; String error; }; struct StringBuilder { void* handle; }; struct Channel_int { void* handle; }; struct Channel_float64 { void* handle; }; bool DirExists(String path); bool Mkdir(String path); String* ListDir(String dir, String ext, int* count); String ReadFile(String path); bool WriteFile(String path, String content); bool FileExists(String path); float64 Sqrt(float64 x); float64 Pow(float64 x, float64 y); int64 Abs(int64 n); float64 AbsF(float64 f); int64 Min(int64 a, int64 b); int64 Max(int64 a, int64 b); float64 MinF(float64 a, float64 b); float64 MaxF(float64 a, float64 b); void* Alloc(uint size); void* Realloc(void* ptr, uint size); void Free(void* ptr); bool MemEq(void* a, void* b, uint size); String Path_Join(String a, String b); String Path_Parent(String path); String Path_Ext(String path); void Task_Init(int num_workers); TaskHandle Task_Spawn(void* fn, void* arg); void Task_Wait(TaskHandle t); void Task_Sleep(int64 ms); void Task_Yield(); int Task_CurrentId(); void Task_Shutdown(); int Os_ArgsCount(); String Os_Args(int index); String Os_GetEnv(String name); bool Os_SetEnv(String name, String value); String Os_GetCwd(); bool Os_Chdir(String path); int64 Time_NowMs(); int64 Time_NowUs(); void Time_SleepMs(int64 ms); int Process_Run(String cmd); String Process_Output(String cmd); int Net_Create(); bool Net_SetReuse(int fd); bool Net_Bind(int fd, String addr, int port); bool Net_Listen(int fd, int backlog); int Net_Accept(int fd); bool Net_Connect(int fd, String addr, int port); int Net_Send(int fd, String data); String Net_Recv(int fd, int maxLen); bool Net_Close(int fd); String Net_LastError(); String Fmt_Fmt3(String tmpl, String a1, String a2, String a3); String Fmt_Fmt2(String tmpl, String a1, String a2); String Fmt_FmtFloat(String tmpl, float64 val); String Fmt_FmtBool(String tmpl, bool val); String Fmt_FmtInt(String tmpl, int64 val); String Fmt_Fmt1(String tmpl, String a1); String Fmt_Format(String tmpl, String* argStrs, int argCount); String Crypto_Sha256(String data); String Crypto_HmacSha256(String key, String message); String Crypto_RandomBytes(int n); String Crypto_Base64Encode(String s); String Crypto_HmacSha256Raw(String key, String message); String Crypto_Base64Decode(String s); Mutex Mutex_New(); void Mutex_Lock(Mutex* m); void Mutex_Unlock(Mutex* m); void Mutex_Free(Mutex* m); RwLock RwLock_New(); void RwLock_ReadLock(RwLock* rw); void RwLock_WriteLock(RwLock* rw); void RwLock_Unlock(RwLock* rw); void RwLock_Free(RwLock* rw); void Test_Exit(int code); void Test_Assert(bool cond); void Test_AssertEqInt(int a, int b); void Test_AssertTrue(bool cond); void Test_AssertFalse(bool cond); void Test_Fail(String msg); Result Result_NewOk(int value); Result Result_NewErr(String msg); bool Result_IsOk(Result r); bool Result_IsErr(Result r); int Result_Unwrap(Result r); int Result_UnwrapOr(Result r, int fallback); Option Option_NewSome(int value); Option Option_NewNone(); bool Option_IsSome(Option o); bool Option_IsNone(Option o); int Option_Unwrap(Option o); int Option_UnwrapOr(Option o, int fallback); JsonValue Json_Null(); JsonValue Json_Bool(bool b); JsonValue Json_Number(float64 n); JsonValue Json_String(String s); JsonValue Json_Array(); JsonValue Json_Object(); uint Json_ArrayLen(JsonValue v); JsonValue Json_ArrayGet(JsonValue v, uint index); void Json_ArrayPush(JsonValue* self, JsonValue val); uint Json_ObjectLen(JsonValue v); JsonValue Json_ObjectGet(JsonValue v, String key); bool Json_ObjectHas(JsonValue v, String key); void Json_ObjectSet(JsonValue* self, String key, JsonValue val); bool Json_IsNull(JsonValue v); bool Json_AsBool(JsonValue v); float64 Json_AsNumber(JsonValue v); String Json_AsString(JsonValue v); int JsonParser_Peek(JsonParser* p); void JsonParser_Advance(JsonParser* p); void JsonParser_SkipWhitespace(JsonParser* p); bool JsonParser_Match(JsonParser* p, String expected); String JsonParser_ParseString(JsonParser* p); JsonValue JsonParser_ParseNumber(JsonParser* p); JsonValue JsonParser_ParseArray(JsonParser* p); JsonValue JsonParser_ParseObject(JsonParser* p); JsonValue JsonParser_ParseValue(JsonParser* p); JsonValue Json_Parse(String s); void Json_StringifyImpl(StringBuilder* sb, JsonValue v); String Json_Stringify(JsonValue v); String Hash_Sha1(String data); String Hash_Sha256(String data); String Hash_Sha384(String data); String Hash_Sha512(String data); void Hash_Sha256Raw(String data, void* out); void Hash_Sha384Raw(String data, void* out); void Hash_Sha512Raw(String data, void* out); int Hash_Sha1Size(); int Hash_Sha256Size(); int Hash_Sha384Size(); int Hash_Sha512Size(); String Base64_Encode(String s); String Base64_Decode(String s); String Base64URL_Encode(String s); String Base64URL_Decode(String s); String Hmac_Sha256(String key, String message); void Hmac_Sha256Raw(String key, String message, void* out); String Hmac_Sha256Base64(String key, String message); String Hmac_Sha384(String key, String message); void Hmac_Sha384Raw(String key, String message, void* out); String Hmac_Sha384Base64(String key, String message); String Hmac_Sha512(String key, String message); void Hmac_Sha512Raw(String key, String message, void* out); String Hmac_Sha512Base64(String key, String message); String Random_Bytes(int n); String Random_Hex(int n); String Random_Base64(int n); uint Random_Uint32(); String Aes_GenerateKey(); String Aes_GenerateIV(); String Aes_CbcEncrypt(String plain, String key, String iv); String Aes_CbcDecrypt(String cipher, String key, String iv); String Aes_GcmEncrypt(String plain, String key, String iv, void* tag); String Aes_GcmDecrypt(String cipher, String key, String iv, String tag); String Jwt_MakeHeader(JwtAlg alg); String Jwt_Sign(JwtAlg alg, String signingInput, String key); bool Jwt_Verify(JwtAlg alg, String signingInput, String signatureB64, String key); String Jwt_Encode(String headerJson, String payloadJson, JwtAlg alg, String key); bool Jwt_Decode(String token, JwtAlg alg, String key, String* headerOut, String* payloadOut); String Jwt_EncodeHS256(String payloadJson, String secret); String Jwt_EncodeHS384(String payloadJson, String secret); String Jwt_EncodeHS512(String payloadJson, String secret); String Jwt_EncodeRS256(String payloadJson, String pemPrivateKey); String Jwt_EncodeES256(String payloadJson, String pemPrivateKey); String Jwt_EncodeEdDSA(String payloadJson, String rawPrivKey); String Ecdsa_SignP256(String pemPrivateKey, String data); String Ecdsa_SignP256Base64(String pemPrivateKey, String data); bool Ecdsa_VerifyP256(String pemPublicKey, String data, String signature); bool Ecdsa_VerifyP256Base64(String pemPublicKey, String data, String signatureB64); String Ecdsa_SignP384(String pemPrivateKey, String data); String Ecdsa_SignP384Base64(String pemPrivateKey, String data); bool Ecdsa_VerifyP384(String pemPublicKey, String data, String signature); bool Ecdsa_VerifyP384Base64(String pemPublicKey, String data, String signatureB64); bool Ed25519_Keypair(void* pubKey, void* privKey); String Ed25519_KeypairBase64(); String Ed25519_Sign(String privKey, String data); String Ed25519_SignBase64(String privKey, String data); bool Ed25519_Verify(String pubKey, String signature, String data); bool Ed25519_VerifyBase64(String pubKey, String signatureB64, String data); String Rsa_SignSha256(String pemPrivateKey, String data); String Rsa_SignSha384(String pemPrivateKey, String data); String Rsa_SignSha512(String pemPrivateKey, String data); String Rsa_SignSha256Base64(String pemPrivateKey, String data); String Rsa_SignSha384Base64(String pemPrivateKey, String data); String Rsa_SignSha512Base64(String pemPrivateKey, String data); bool Rsa_VerifySha256(String pemPublicKey, String data, String signature); bool Rsa_VerifySha384(String pemPublicKey, String data, String signature); bool Rsa_VerifySha512(String pemPublicKey, String data, String signature); bool Rsa_VerifySha256Base64(String pemPublicKey, String data, String signatureB64); bool Rsa_VerifySha384Base64(String pemPublicKey, String data, String signatureB64); bool Rsa_VerifySha512Base64(String pemPublicKey, String data, String signatureB64); uint String_Len(String s); bool String_IsNull(String s); bool String_Eq(String a, String b); String String_Concat(String a, String b); String String_Copy(String s); bool String_StartsWith(String s, String prefix); bool String_EndsWith(String s, String suffix); bool String_Contains(String s, String substr); String String_Slice(String s, uint start, uint len); String String_Trim(String s); String String_TrimLeft(String s); String String_TrimRight(String s); String String_FromInt(int64 n); int64 String_ToInt(String s); StringBuilder StringBuilder_New(); StringBuilder StringBuilder_NewCap(uint cap); void StringBuilder_Append(StringBuilder* sb, String s); void StringBuilder_AppendInt(StringBuilder* sb, int64 n); void StringBuilder_AppendFloat(StringBuilder* sb, float64 f); void StringBuilder_AppendChar(StringBuilder* sb, char8 c); String StringBuilder_Build(StringBuilder* sb); void StringBuilder_Free(StringBuilder* sb); uint String_SplitCount(String s, String delim); String String_SplitPart(String s, String delim, uint index); String String_Join2(String a, String b, String sep); String String_Chars(String s, uint index); String String_Find(String haystack, String needle); uint String_Offset(String pos, String base); String String_Replace(String s, String old, String new); float64 String_ToFloat(String s); String String_FromBool(bool b); String String_FromFloat(float64 f); String String_Format1(String pattern, String a0); String String_Format2(String pattern, String a0, String a1); String String_Format3(String pattern, String a0, String a1, String a2); void Channel_SendInt(Channel_int* ch, int value); int Channel_RecvInt(Channel_int* ch); void Channel_SendFloat64(Channel_float64* ch, float64 value); float64 Channel_RecvFloat64(Channel_float64* ch); int Main(); int bux_dir_exists(String path); int bux_mkdir_if_needed(String path); String* bux_list_dir(String dir, String ext, int* out_count); void PrintLine(String s); void Print(String s); void PrintInt(int n); void PrintInt64(int64 n); void PrintFloat(float64 f); void PrintBool(bool b); String ReadLine(); String bux_read_file(String path); int bux_write_file(String path, String content); int bux_file_exists(String path); float64 bux_sqrt(float64 x); float64 bux_pow(float64 x, float64 y); int64 bux_abs_i64(int64 x); float64 bux_abs_f64(float64 x); int64 bux_min_i64(int64 a, int64 b); int64 bux_max_i64(int64 a, int64 b); float64 bux_min_f64(float64 a, float64 b); float64 bux_max_f64(float64 a, float64 b); void* bux_alloc(uint size); void* bux_realloc(void* ptr, uint size); void bux_free(void* ptr); int bux_mem_eq(void* a, void* b, uint size); String bux_path_join(String a, String b); String bux_path_parent(String path); String bux_path_ext(String path); void bux_task_init(int num_workers); void* bux_task_spawn(void* fn, void* arg); void bux_task_join(void* handle); void bux_task_sleep(int64 ms); void bux_task_yield(); int bux_task_current_id(); void bux_task_shutdown(); int bux_argc(); String bux_argv(int index); String bux_getenv(String name); int bux_setenv(String name, String value); String bux_getcwd(); int bux_chdir(String path); int64 bux_time_ms(); int64 bux_time_us(); void bux_sleep_ms(int64 ms); int bux_process_run(String cmd); String bux_process_output(String cmd); int bux_socket_create(); int bux_socket_reuse(int fd); int bux_socket_bind(int fd, String addr, int port); int bux_socket_listen(int fd, int backlog); int bux_socket_accept(int fd); int bux_socket_connect(int fd, String addr, int port); int bux_socket_send(int fd, String data, int len); String bux_socket_recv(int fd, int maxLen); int bux_socket_close(int fd); String bux_socket_error(); void* bux_alloc(uint size); int64 bux_str_to_int(String s); uint bux_strlen(String s); void bux_sha256(String data, int len, void* out); void bux_hmac_sha256(String key, int keylen, String msg, int msglen, void* out); int bux_random_bytes(void* buf, int len); String bux_base64_encode(String data, int len); String bux_base64_decode(String data, int len, int* outlen); String bux_bytes_to_hex(void* data, int len); void* bux_mutex_new(); void bux_mutex_lock(void* handle); void bux_mutex_unlock(void* handle); void bux_mutex_free(void* handle); void* bux_rwlock_new(); void bux_rwlock_rdlock(void* handle); void bux_rwlock_wrlock(void* handle); void bux_rwlock_unlock(void* handle); void bux_rwlock_free(void* handle); void bux_exit(int code); void bux_assert(int cond, String file, int line, String expr); void bux_sha1(String data, int len, void* out); void bux_sha256(String data, int len, void* out); void bux_sha384(String data, int len, void* out); void bux_sha512(String data, int len, void* out); String bux_bytes_to_hex(void* data, int len); String bux_base64_encode(String data, int len); String bux_base64_decode(String data, int len, int* outlen); String bux_base64url_encode(String data, int len); String bux_base64url_decode(String data, int len, int* outlen); void bux_hmac_sha256(String key, int keylen, String msg, int msglen, void* out); void bux_hmac_sha384(String key, int keylen, String msg, int msglen, void* out); void bux_hmac_sha512(String key, int keylen, String msg, int msglen, void* out); String bux_bytes_to_hex(void* data, int len); String bux_base64_encode(String data, int len); int bux_random_bytes(void* buf, int len); String bux_base64_encode(String data, int len); String bux_bytes_to_hex(void* data, int len); int bux_random_bytes(void* buf, int len); String bux_aes_256_cbc_encrypt(String plain, int plainlen, String key, String iv, int* outlen); String bux_aes_256_cbc_decrypt(String cipher, int cipherlen, String key, String iv, int* outlen); String bux_aes_256_gcm_encrypt(String plain, int plainlen, String key, String iv, void* tag, int* outlen); String bux_aes_256_gcm_decrypt(String cipher, int cipherlen, String key, String iv, String tag, int* outlen); String bux_base64_encode(String data, int len); uint bux_str_split_count(String s, String delim); String bux_str_split_part(String s, String delim, uint index); String bux_ecdsa_sign_p256(String key, int keylen, String data, int datalen, int* outlen); int bux_ecdsa_verify_p256(String key, int keylen, String data, int datalen, String sig, int siglen); String bux_ecdsa_sign_p384(String key, int keylen, String data, int datalen, int* outlen); int bux_ecdsa_verify_p384(String key, int keylen, String data, int datalen, String sig, int siglen); String bux_base64_encode(String data, int len); String bux_base64_decode(String data, int len, int* outlen); int bux_ed25519_keypair(void* pubKey, void* privKey); int bux_ed25519_sign(String privKey, String data, int datalen, void* sig); int bux_ed25519_verify(String pubKey, String sig, String data, int datalen); String bux_base64_encode(String data, int len); String bux_base64_decode(String data, int len, int* outlen); String bux_rsa_sign_sha256(String key, int keylen, String data, int datalen, int* outlen); String bux_rsa_sign_sha384(String key, int keylen, String data, int datalen, int* outlen); String bux_rsa_sign_sha512(String key, int keylen, String data, int datalen, int* outlen); int bux_rsa_verify_sha256(String key, int keylen, String data, int datalen, String sig, int siglen); int bux_rsa_verify_sha384(String key, int keylen, String data, int datalen, String sig, int siglen); int bux_rsa_verify_sha512(String key, int keylen, String data, int datalen, String sig, int siglen); String bux_base64_encode(String data, int len); String bux_base64_decode(String data, int len, int* outlen); uint bux_strlen(String s); int bux_strcmp(String a, String b); int bux_strncmp(String a, String b, uint n); char8* bux_strcpy(char8* dest, String src); char8* bux_strcat(char8* dest, String src); char8* bux_strncpy(char8* dest, String src, uint n); String bux_strstr(String haystack, String needle); int bux_str_contains(String haystack, String needle); uint bux_str_offset(String pos, String base); int bux_str_is_null(String s); String bux_str_slice(String s, uint start, uint len); String bux_str_trim_left(String s); String bux_str_trim_right(String s); String bux_str_trim(String s); String bux_int_to_str(int64 n); int64 bux_str_to_int(String s); void* bux_sb_new(uint initial_cap); void bux_sb_append(void* sb, String s); void bux_sb_append_int(void* sb, int64 n); void bux_sb_append_float(void* sb, float64 f); void bux_sb_append_char(void* sb, char8 c); String bux_sb_build(void* sb); void bux_sb_free(void* sb); uint bux_str_split_count(String s, String delim); String bux_str_split_part(String s, String delim, uint index); String bux_str_join2(String a, String b, String sep); String bux_float_to_string(float64 f); String bux_str_format(String pattern, String a0, String a1, String a2, String a3, String a4, String a5, String a6, String a7); float64 bux_str_to_float(String s); void bux_bounds_check(uint index, uint len); void* bux_alloc(uint size); void* bux_realloc(void* ptr, uint size); void bux_free(void* ptr); void bux_bounds_check(uint index, uint len); void* bux_channel_new(int64 capacity, int64 elem_size); void bux_channel_send(void* handle, void* elem); int bux_channel_recv(void* handle, void* out); void bux_channel_close(void* handle); void bux_channel_free(void* handle); uint bux_hash_bytes(void* ptr, uint size); uint bux_hash_string(String s); uint bux_hash_bytes(void* ptr, uint size); int bux_mem_eq(void* a, void* b, uint size); void* bux_alloc(uint size); void bux_free(void* ptr); bool DirExists(String path) { return bux_dir_exists(path) != 0; } bool Mkdir(String path) { return bux_mkdir_if_needed(path) != 0; } String* ListDir(String dir, String ext, int* count) { return bux_list_dir(dir, ext, count); } String ReadFile(String path) { return bux_read_file(path); } bool WriteFile(String path, String content) { int r = bux_write_file(path, content); return r != 0; } bool FileExists(String path) { int r = bux_file_exists(path); return r != 0; } float64 Sqrt(float64 x) { return bux_sqrt(x); } float64 Pow(float64 x, float64 y) { return bux_pow(x, y); } int64 Abs(int64 n) { return bux_abs_i64(n); } float64 AbsF(float64 f) { return bux_abs_f64(f); } int64 Min(int64 a, int64 b) { return bux_min_i64(a, b); } int64 Max(int64 a, int64 b) { return bux_max_i64(a, b); } float64 MinF(float64 a, float64 b) { return bux_min_f64(a, b); } float64 MaxF(float64 a, float64 b) { return bux_max_f64(a, b); } void* Alloc(uint size) { return bux_alloc(size); } void* Realloc(void* ptr, uint size) { return bux_realloc(ptr, size); } void Free(void* ptr) { bux_free(ptr); } bool MemEq(void* a, void* b, uint size) { return bux_mem_eq(a, b, size) != 0; } String Path_Join(String a, String b) { return bux_path_join(a, b); } String Path_Parent(String path) { return bux_path_parent(path); } String Path_Ext(String path) { return bux_path_ext(path); } void Task_Init(int num_workers) { bux_task_init(num_workers); } TaskHandle Task_Spawn(void* fn, void* arg) { return ((TaskHandle){.handle = bux_task_spawn(fn, arg)}); } void Task_Wait(TaskHandle t) { bux_task_join(t.handle); } void Task_Sleep(int64 ms) { bux_task_sleep(ms); } void Task_Yield() { bux_task_yield(); } int Task_CurrentId() { return bux_task_current_id(); } void Task_Shutdown() { bux_task_shutdown(); } int Os_ArgsCount() { return bux_argc(); } String Os_Args(int index) { return bux_argv(index); } String Os_GetEnv(String name) { return bux_getenv(name); } bool Os_SetEnv(String name, String value) { return bux_setenv(name, value) == 0; } String Os_GetCwd() { return bux_getcwd(); } bool Os_Chdir(String path) { return bux_chdir(path) == 0; } int64 Time_NowMs() { return bux_time_ms(); } int64 Time_NowUs() { return bux_time_us(); } void Time_SleepMs(int64 ms) { bux_sleep_ms(ms); } int Process_Run(String cmd) { return bux_process_run(cmd); } String Process_Output(String cmd) { return bux_process_output(cmd); } int Net_Create() { return bux_socket_create(); } bool Net_SetReuse(int fd) { return bux_socket_reuse(fd) == 0; } bool Net_Bind(int fd, String addr, int port) { return bux_socket_bind(fd, addr, port) == 0; } bool Net_Listen(int fd, int backlog) { return bux_socket_listen(fd, backlog) == 0; } int Net_Accept(int fd) { return bux_socket_accept(fd); } bool Net_Connect(int fd, String addr, int port) { return bux_socket_connect(fd, addr, port) == 0; } int Net_Send(int fd, String data) { return bux_socket_send(fd, data, ((int)bux_strlen(data))); } String Net_Recv(int fd, int maxLen) { return bux_socket_recv(fd, maxLen); } bool Net_Close(int fd) { return bux_socket_close(fd) == 0; } String Net_LastError() { return bux_socket_error(); } String Fmt_Fmt3(String tmpl, String a1, String a2, String a3) { String* args = ((String*)bux_alloc(3 * sizeof(String))); args[0] = a1; args[1] = a2; args[2] = a3; return Fmt_Format(tmpl, args, 3); } String Fmt_Fmt2(String tmpl, String a1, String a2) { String* args = ((String*)bux_alloc(2 * sizeof(String))); args[0] = a1; args[1] = a2; return Fmt_Format(tmpl, args, 2); } String Fmt_FmtFloat(String tmpl, float64 val) { String s = String_FromFloat(val); return Fmt_Fmt1(tmpl, s); } String Fmt_FmtBool(String tmpl, bool val) { String s = String_FromBool(val); return Fmt_Fmt1(tmpl, s); } String Fmt_FmtInt(String tmpl, int64 val) { String s = String_FromInt(val); return Fmt_Fmt1(tmpl, s); } String Fmt_Fmt1(String tmpl, String a1) { String* args = ((String*)bux_alloc(sizeof(String))); args[0] = a1; return Fmt_Format(tmpl, args, 1); } String Fmt_Format(String tmpl, String* argStrs, int argCount) { StringBuilder sb = StringBuilder_New(); uint i = 0; uint tmplLen = bux_strlen(tmpl); while (i < tmplLen) { String ch = String_Chars(tmpl, i); if (String_Eq(ch, "{")) { uint digitIdx = i + 1; if (digitIdx < tmplLen) { String digitCh = String_Chars(tmpl, digitIdx); int64 d = bux_str_to_int(digitCh); if (d >= 0 && d < ((int64)argCount)) { i = i + 2; if (i < tmplLen) { String closeCh = String_Chars(tmpl, i); if (String_Eq(closeCh, "}")) { i = i + 1; String argStr = argStrs[((uint)d)]; StringBuilder_Append(&sb, argStr); continue; } } } } } StringBuilder_Append(&sb, ch); i = i + 1; } return StringBuilder_Build(&sb); } String Crypto_Sha256(String data) { int len = ((int)String_Len(data)); void* hashBuf = Alloc(32); bux_sha256(data, len, hashBuf); String result = bux_bytes_to_hex(((void*)hashBuf), 32); Free(hashBuf); return result; } String Crypto_HmacSha256(String key, String message) { int keylen = ((int)String_Len(key)); int msglen = ((int)String_Len(message)); void* hmacBuf = Alloc(32); bux_hmac_sha256(key, keylen, message, msglen, hmacBuf); String result = bux_bytes_to_hex(((void*)hmacBuf), 32); Free(hmacBuf); return result; } String Crypto_RandomBytes(int n) { if (n <= 0) { return ""; } void* buf = Alloc(((uint)n)); if (bux_random_bytes(buf, n) != 1) { Free(buf); return ""; } String result = bux_base64_encode(((String)buf), n); Free(buf); return result; } String Crypto_Base64Encode(String s) { return bux_base64_encode(s, ((int)String_Len(s))); } String Crypto_HmacSha256Raw(String key, String message) { int keylen = ((int)String_Len(key)); int msglen = ((int)String_Len(message)); void* hmacBuf = Alloc(32); bux_hmac_sha256(key, keylen, message, msglen, hmacBuf); String result = bux_base64_encode(((String)hmacBuf), 32); Free(hmacBuf); return result; } String Crypto_Base64Decode(String s) { int outlen = 0; return bux_base64_decode(s, ((int)String_Len(s)), &outlen); } Mutex Mutex_New() { return ((Mutex){.handle = bux_mutex_new()}); } void Mutex_Lock(Mutex* m) { bux_mutex_lock(m->handle); } void Mutex_Unlock(Mutex* m) { bux_mutex_unlock(m->handle); } void Mutex_Free(Mutex* m) { bux_mutex_free(m->handle); } RwLock RwLock_New() { return ((RwLock){.handle = bux_rwlock_new()}); } void RwLock_ReadLock(RwLock* rw) { bux_rwlock_rdlock(rw->handle); } void RwLock_WriteLock(RwLock* rw) { bux_rwlock_wrlock(rw->handle); } void RwLock_Unlock(RwLock* rw) { bux_rwlock_unlock(rw->handle); } void RwLock_Free(RwLock* rw) { bux_rwlock_free(rw->handle); } void Test_Exit(int code) { bux_exit(code); } void Test_Assert(bool cond) { bux_assert(((int)cond), "", 0, ""); } void Test_AssertEqInt(int a, int b) { if (a != b) { PrintLine("ASSERT_EQ FAILED:"); PrintInt(a); PrintLine(" != "); PrintInt(b); bux_exit(1); } } void Test_AssertTrue(bool cond) { if (!cond) { PrintLine("ASSERT_TRUE FAILED"); bux_exit(1); } } void Test_AssertFalse(bool cond) { if (cond) { PrintLine("ASSERT_FALSE FAILED"); bux_exit(1); } } void Test_Fail(String msg) { PrintLine("FAIL:"); PrintLine(msg); bux_exit(1); } Result Result_NewOk(int value) { Result r = ((Result){.tag = Result_Ok}); r.data.Ok_0 = value; return r; } Result Result_NewErr(String msg) { Result r = ((Result){.tag = Result_Err}); r.data.Err_0 = msg; return r; } bool Result_IsOk(Result r) { return r.tag == Result_Ok; } bool Result_IsErr(Result r) { return r.tag == Result_Err; } int Result_Unwrap(Result r) { if (r.tag != Result_Ok) { PrintLine("panic: unwrap on Err"); return 0; } return r.data.Ok_0; } int Result_UnwrapOr(Result r, int fallback) { if (r.tag == Result_Ok) { return r.data.Ok_0; } return fallback; } Option Option_NewSome(int value) { Option o = ((Option){.tag = Option_Some}); o.data.Some_0 = value; return o; } Option Option_NewNone() { return ((Option){.tag = Option_None}); } bool Option_IsSome(Option o) { return o.tag == Option_Some; } bool Option_IsNone(Option o) { return o.tag == Option_None; } int Option_Unwrap(Option o) { if (o.tag != Option_Some) { PrintLine("panic: unwrap on None"); return 0; } return o.data.Some_0; } int Option_UnwrapOr(Option o, int fallback) { if (o.tag == Option_Some) { return o.data.Some_0; } return fallback; } JsonValue Json_Null() { return ((JsonValue){.tag = JsonTagNull, .boolVal = false, .numVal = 0.0, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0}); } JsonValue Json_Bool(bool b) { return ((JsonValue){.tag = JsonTagBool, .boolVal = b, .numVal = 0.0, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0}); } JsonValue Json_Number(float64 n) { return ((JsonValue){.tag = JsonTagNumber, .boolVal = false, .numVal = n, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0}); } JsonValue Json_String(String s) { return ((JsonValue){.tag = JsonTagString, .boolVal = false, .numVal = 0.0, .strVal = s, .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0}); } JsonValue Json_Array() { return ((JsonValue){.tag = JsonTagArray, .boolVal = false, .numVal = 0.0, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0}); } JsonValue Json_Object() { return ((JsonValue){.tag = JsonTagObject, .boolVal = false, .numVal = 0.0, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0}); } uint Json_ArrayLen(JsonValue v) { if (v.tag != JsonTagArray) { return 0; } return v.arrLen; } JsonValue Json_ArrayGet(JsonValue v, uint index) { if (v.tag != JsonTagArray) { return Json_Null(); } if (index >= v.arrLen) { return Json_Null(); } return v.arrData[index]; } void Json_ArrayPush(JsonValue* self, JsonValue val) { if (self->tag != JsonTagArray) { return; } if (self->arrLen >= self->arrCap) { uint arrNewCap = self->arrCap; if (arrNewCap == 0) { self->arrCap = 4; self->arrData = ((JsonValue*)Alloc(4 * sizeof(JsonValue))); } else { uint doubleCap = arrNewCap * 2; self->arrCap = doubleCap; self->arrData = ((JsonValue*)Realloc(((void*)self->arrData), doubleCap * sizeof(JsonValue))); } } self->arrData[self->arrLen] = val; self->arrLen = self->arrLen + 1; } uint Json_ObjectLen(JsonValue v) { if (v.tag != JsonTagObject) { return 0; } return v.objLen; } JsonValue Json_ObjectGet(JsonValue v, String key) { if (v.tag != JsonTagObject) { return Json_Null(); } uint i = 0; while (i < v.objLen) { if (String_Eq(v.objKeys[i], key)) { return v.objValues[i]; } i = i + 1; } return Json_Null(); } bool Json_ObjectHas(JsonValue v, String key) { if (v.tag != JsonTagObject) { return false; } uint i = 0; while (i < v.objLen) { if (String_Eq(v.objKeys[i], key)) { return true; } i = i + 1; } return false; } void Json_ObjectSet(JsonValue* self, String key, JsonValue val) { if (self->tag != JsonTagObject) { return; } uint i = 0; while (i < self->objLen) { if (String_Eq(self->objKeys[i], key)) { self->objValues[i] = val; return; } i = i + 1; } if (self->objLen >= self->objCap) { uint objNewCap = self->objCap; if (objNewCap == 0) { self->objCap = 4; self->objKeys = ((String*)Alloc(4 * sizeof(String))); self->objValues = ((JsonValue*)Alloc(4 * sizeof(JsonValue))); } else { uint doubleCap = objNewCap * 2; self->objCap = doubleCap; self->objKeys = ((String*)Realloc(((void*)self->objKeys), doubleCap * sizeof(String))); self->objValues = ((JsonValue*)Realloc(((void*)self->objValues), doubleCap * sizeof(JsonValue))); } } self->objKeys[self->objLen] = key; self->objValues[self->objLen] = val; self->objLen = self->objLen + 1; } bool Json_IsNull(JsonValue v) { return v.tag == JsonTagNull; } bool Json_AsBool(JsonValue v) { if (v.tag == JsonTagBool) { return v.boolVal; } return false; } float64 Json_AsNumber(JsonValue v) { if (v.tag == JsonTagNumber) { return v.numVal; } return 0.0; } String Json_AsString(JsonValue v) { if (v.tag == JsonTagString) { return v.strVal; } return ""; } int JsonParser_Peek(JsonParser* p) { if (p->pos >= p->len) { return 0; } return ((int)p->src[p->pos]); } void JsonParser_Advance(JsonParser* p) { if (p->pos < p->len) { p->pos = p->pos + 1; } } void JsonParser_SkipWhitespace(JsonParser* p) { while (true) { int c = JsonParser_Peek(p); if (c == 32 || c == 9 || c == 10 || c == 13) { JsonParser_Advance(p); } else { return; } } } bool JsonParser_Match(JsonParser* p, String expected) { uint elen = String_Len(expected); if (p->pos + elen > p->len) { return false; } uint i = 0; while (i < elen) { if (p->src[p->pos + i] != expected[i]) { return false; } i = i + 1; } p->pos = p->pos + elen; return true; } String JsonParser_ParseString(JsonParser* p) { if (JsonParser_Peek(p) != 34) { p->error = "Expected string"; return ""; } JsonParser_Advance(p); StringBuilder sb = StringBuilder_New(); while (true) { int c = JsonParser_Peek(p); if (c == 0 || c == 34) { break; } if (c == 92) { JsonParser_Advance(p); int esc = JsonParser_Peek(p); if (esc == 0) { p->error = "Unterminated string escape"; StringBuilder_Free(&sb); return ""; } if (esc == 110) { StringBuilder_AppendChar(&sb, ((char8)10)); } else { if (esc == 116) { StringBuilder_AppendChar(&sb, ((char8)9)); } else { if (esc == 114) { StringBuilder_AppendChar(&sb, ((char8)13)); } else { if (esc == 98) { StringBuilder_AppendChar(&sb, ((char8)8)); } else { if (esc == 102) { StringBuilder_AppendChar(&sb, ((char8)12)); } else { if (esc == 34) { StringBuilder_AppendChar(&sb, ((char8)34)); } else { if (esc == 92) { StringBuilder_AppendChar(&sb, ((char8)92)); } else { StringBuilder_AppendChar(&sb, ((char8)92)); StringBuilder_AppendChar(&sb, ((char8)esc)); } } } } } } } JsonParser_Advance(p); } else { StringBuilder_AppendChar(&sb, ((char8)c)); JsonParser_Advance(p); } } if (JsonParser_Peek(p) != 34) { p->error = "Unterminated string"; StringBuilder_Free(&sb); return ""; } JsonParser_Advance(p); String result = StringBuilder_Build(&sb); StringBuilder_Free(&sb); return result; } JsonValue JsonParser_ParseNumber(JsonParser* p) { uint start = p->pos; int c0 = JsonParser_Peek(p); if (c0 == 45) { JsonParser_Advance(p); } while (true) { int c = JsonParser_Peek(p); if (c >= 48 && c <= 57) { JsonParser_Advance(p); } else { break; } } if (JsonParser_Peek(p) == 46) { JsonParser_Advance(p); while (true) { int c = JsonParser_Peek(p); if (c >= 48 && c <= 57) { JsonParser_Advance(p); } else { break; } } } String numStr = String_Slice(p->src, start, p->pos - start); float64 n = String_ToFloat(numStr); return Json_Number(n); } JsonValue JsonParser_ParseArray(JsonParser* p) { JsonParser_Advance(p); JsonValue arr = Json_Array(); JsonParser_SkipWhitespace(p); if (JsonParser_Peek(p) == 93) { JsonParser_Advance(p); return arr; } while (true) { JsonParser_SkipWhitespace(p); JsonValue val = JsonParser_ParseValue(p); if (p->error != "") { return Json_Null(); } Json_ArrayPush(&arr, val); JsonParser_SkipWhitespace(p); int c = JsonParser_Peek(p); if (c == 93) { JsonParser_Advance(p); return arr; } if (c == 44) { JsonParser_Advance(p); } else { p->error = "Expected ',' or ']' in array"; return Json_Null(); } } } JsonValue JsonParser_ParseObject(JsonParser* p) { JsonParser_Advance(p); JsonValue obj = Json_Object(); JsonParser_SkipWhitespace(p); if (JsonParser_Peek(p) == 125) { JsonParser_Advance(p); return obj; } while (true) { JsonParser_SkipWhitespace(p); String key = JsonParser_ParseString(p); if (p->error != "") { return Json_Null(); } JsonParser_SkipWhitespace(p); if (JsonParser_Peek(p) != 58) { p->error = "Expected ':' after object key"; return Json_Null(); } JsonParser_Advance(p); JsonParser_SkipWhitespace(p); JsonValue val = JsonParser_ParseValue(p); if (p->error != "") { return Json_Null(); } Json_ObjectSet(&obj, key, val); JsonParser_SkipWhitespace(p); int c = JsonParser_Peek(p); if (c == 125) { JsonParser_Advance(p); return obj; } if (c == 44) { JsonParser_Advance(p); } else { p->error = "Expected ',' or '}' in object"; return Json_Null(); } } } JsonValue JsonParser_ParseValue(JsonParser* p) { JsonParser_SkipWhitespace(p); int c = JsonParser_Peek(p); if (c == 0) { p->error = "Unexpected end of input"; return Json_Null(); } if (c == 34) { return Json_String(JsonParser_ParseString(p)); } if (c == 123) { return JsonParser_ParseObject(p); } if (c == 91) { return JsonParser_ParseArray(p); } if (c == 116) { if (JsonParser_Match(p, "true")) { return Json_Bool(true); } p->error = "Expected 'true'"; return Json_Null(); } if (c == 102) { if (JsonParser_Match(p, "false")) { return Json_Bool(false); } p->error = "Expected 'false'"; return Json_Null(); } if (c == 110) { if (JsonParser_Match(p, "null")) { return Json_Null(); } p->error = "Expected 'null'"; return Json_Null(); } if (c >= 48 && c <= 57 || c == 45) { return JsonParser_ParseNumber(p); } p->error = "Unexpected character"; return Json_Null(); } JsonValue Json_Parse(String s) { JsonParser p = ((JsonParser){.src = s, .pos = 0, .len = String_Len(s), .error = ""}); JsonValue result = JsonParser_ParseValue(&p); JsonParser_SkipWhitespace(&p); if (p.error == "" && p.pos != p.len) { p.error = "Trailing data after JSON value"; return Json_Null(); } return result; } void Json_StringifyImpl(StringBuilder* sb, JsonValue v) { if (v.tag == JsonTagNull) { StringBuilder_Append(sb, "null"); return; } if (v.tag == JsonTagBool) { if (v.boolVal) { StringBuilder_Append(sb, "true"); } else { StringBuilder_Append(sb, "false"); } return; } if (v.tag == JsonTagNumber) { StringBuilder_AppendFloat(sb, v.numVal); return; } if (v.tag == JsonTagString) { StringBuilder_AppendChar(sb, ((char8)34)); StringBuilder_Append(sb, v.strVal); StringBuilder_AppendChar(sb, ((char8)34)); return; } if (v.tag == JsonTagArray) { StringBuilder_AppendChar(sb, ((char8)91)); uint i = 0; while (i < v.arrLen) { if (i > 0) { StringBuilder_AppendChar(sb, ((char8)44)); } Json_StringifyImpl(sb, v.arrData[i]); i = i + 1; } StringBuilder_AppendChar(sb, ((char8)93)); return; } if (v.tag == JsonTagObject) { StringBuilder_AppendChar(sb, ((char8)123)); uint i = 0; while (i < v.objLen) { if (i > 0) { StringBuilder_AppendChar(sb, ((char8)44)); } StringBuilder_AppendChar(sb, ((char8)34)); StringBuilder_Append(sb, v.objKeys[i]); StringBuilder_AppendChar(sb, ((char8)34)); StringBuilder_AppendChar(sb, ((char8)58)); Json_StringifyImpl(sb, v.objValues[i]); i = i + 1; } StringBuilder_AppendChar(sb, ((char8)125)); return; } } String Json_Stringify(JsonValue v) { StringBuilder sb = StringBuilder_New(); Json_StringifyImpl(&sb, v); return StringBuilder_Build(&sb); } String Hash_Sha1(String data) { int len = ((int)String_Len(data)); void* buf = Alloc(20); bux_sha1(data, len, buf); String result = bux_bytes_to_hex(buf, 20); Free(buf); return result; } String Hash_Sha256(String data) { int len = ((int)String_Len(data)); void* buf = Alloc(32); bux_sha256(data, len, buf); String result = bux_bytes_to_hex(buf, 32); Free(buf); return result; } String Hash_Sha384(String data) { int len = ((int)String_Len(data)); void* buf = Alloc(48); bux_sha384(data, len, buf); String result = bux_bytes_to_hex(buf, 48); Free(buf); return result; } String Hash_Sha512(String data) { int len = ((int)String_Len(data)); void* buf = Alloc(64); bux_sha512(data, len, buf); String result = bux_bytes_to_hex(buf, 64); Free(buf); return result; } void Hash_Sha256Raw(String data, void* out) { bux_sha256(data, ((int)String_Len(data)), out); } void Hash_Sha384Raw(String data, void* out) { bux_sha384(data, ((int)String_Len(data)), out); } void Hash_Sha512Raw(String data, void* out) { bux_sha512(data, ((int)String_Len(data)), out); } int Hash_Sha1Size() { return 20; } int Hash_Sha256Size() { return 32; } int Hash_Sha384Size() { return 48; } int Hash_Sha512Size() { return 64; } String Base64_Encode(String s) { return bux_base64_encode(s, ((int)String_Len(s))); } String Base64_Decode(String s) { int outlen = 0; return bux_base64_decode(s, ((int)String_Len(s)), &outlen); } String Base64URL_Encode(String s) { return bux_base64url_encode(s, ((int)String_Len(s))); } String Base64URL_Decode(String s) { int outlen = 0; return bux_base64url_decode(s, ((int)String_Len(s)), &outlen); } String Hmac_Sha256(String key, String message) { int kl = ((int)String_Len(key)); int ml = ((int)String_Len(message)); void* buf = Alloc(32); bux_hmac_sha256(key, kl, message, ml, buf); String result = bux_bytes_to_hex(buf, 32); Free(buf); return result; } void Hmac_Sha256Raw(String key, String message, void* out) { bux_hmac_sha256(key, ((int)String_Len(key)), message, ((int)String_Len(message)), out); } String Hmac_Sha256Base64(String key, String message) { int kl = ((int)String_Len(key)); int ml = ((int)String_Len(message)); void* buf = Alloc(32); bux_hmac_sha256(key, kl, message, ml, buf); String result = bux_base64_encode(((String)buf), 32); Free(buf); return result; } String Hmac_Sha384(String key, String message) { int kl = ((int)String_Len(key)); int ml = ((int)String_Len(message)); void* buf = Alloc(48); bux_hmac_sha384(key, kl, message, ml, buf); String result = bux_bytes_to_hex(buf, 48); Free(buf); return result; } void Hmac_Sha384Raw(String key, String message, void* out) { bux_hmac_sha384(key, ((int)String_Len(key)), message, ((int)String_Len(message)), out); } String Hmac_Sha384Base64(String key, String message) { int kl = ((int)String_Len(key)); int ml = ((int)String_Len(message)); void* buf = Alloc(48); bux_hmac_sha384(key, kl, message, ml, buf); String result = bux_base64_encode(((String)buf), 48); Free(buf); return result; } String Hmac_Sha512(String key, String message) { int kl = ((int)String_Len(key)); int ml = ((int)String_Len(message)); void* buf = Alloc(64); bux_hmac_sha512(key, kl, message, ml, buf); String result = bux_bytes_to_hex(buf, 64); Free(buf); return result; } void Hmac_Sha512Raw(String key, String message, void* out) { bux_hmac_sha512(key, ((int)String_Len(key)), message, ((int)String_Len(message)), out); } String Hmac_Sha512Base64(String key, String message) { int kl = ((int)String_Len(key)); int ml = ((int)String_Len(message)); void* buf = Alloc(64); bux_hmac_sha512(key, kl, message, ml, buf); String result = bux_base64_encode(((String)buf), 64); Free(buf); return result; } String Random_Bytes(int n) { if (n <= 0) { return ""; } void* buf = Alloc(((uint)n)); if (bux_random_bytes(buf, n) != 1) { Free(buf); return ""; } return ((String)buf); } String Random_Hex(int n) { if (n <= 0) { return ""; } void* buf = Alloc(((uint)n)); if (bux_random_bytes(buf, n) != 1) { Free(buf); return ""; } String result = bux_bytes_to_hex(buf, n); Free(buf); return result; } String Random_Base64(int n) { if (n <= 0) { return ""; } void* buf = Alloc(((uint)n)); if (bux_random_bytes(buf, n) != 1) { Free(buf); return ""; } String result = bux_base64_encode(((String)buf), n); Free(buf); return result; } uint Random_Uint32() { void* buf = Alloc(4); if (bux_random_bytes(buf, 4) != 1) { Free(buf); return 0; } uint* ptr = ((uint*)buf); uint val = *ptr; Free(buf); return val; } String Aes_GenerateKey() { void* buf = Alloc(((uint)AES_KEY_SIZE)); if (bux_random_bytes(buf, AES_KEY_SIZE) != 1) { Free(buf); return ""; } return ((String)buf); } String Aes_GenerateIV() { void* buf = Alloc(((uint)AES_IV_SIZE)); if (bux_random_bytes(buf, AES_IV_SIZE) != 1) { Free(buf); return ""; } return ((String)buf); } String Aes_CbcEncrypt(String plain, String key, String iv) { int outlen = 0; return bux_aes_256_cbc_encrypt(plain, ((int)String_Len(plain)), key, iv, &outlen); } String Aes_CbcDecrypt(String cipher, String key, String iv) { int outlen = 0; return bux_aes_256_cbc_decrypt(cipher, ((int)String_Len(cipher)), key, iv, &outlen); } String Aes_GcmEncrypt(String plain, String key, String iv, void* tag) { int outlen = 0; return bux_aes_256_gcm_encrypt(plain, ((int)String_Len(plain)), key, iv, tag, &outlen); } String Aes_GcmDecrypt(String cipher, String key, String iv, String tag) { int outlen = 0; return bux_aes_256_gcm_decrypt(cipher, ((int)String_Len(cipher)), key, iv, tag, &outlen); } String Jwt_MakeHeader(JwtAlg alg) { if (alg.tag == JwtAlg_HS256) { return "{\"alg\":\"HS256\",\"typ\":\"JWT\"}"; } if (alg.tag == JwtAlg_HS384) { return "{\"alg\":\"HS384\",\"typ\":\"JWT\"}"; } if (alg.tag == JwtAlg_HS512) { return "{\"alg\":\"HS512\",\"typ\":\"JWT\"}"; } if (alg.tag == JwtAlg_RS256) { return "{\"alg\":\"RS256\",\"typ\":\"JWT\"}"; } if (alg.tag == JwtAlg_RS384) { return "{\"alg\":\"RS384\",\"typ\":\"JWT\"}"; } if (alg.tag == JwtAlg_RS512) { return "{\"alg\":\"RS512\",\"typ\":\"JWT\"}"; } if (alg.tag == JwtAlg_ES256) { return "{\"alg\":\"ES256\",\"typ\":\"JWT\"}"; } if (alg.tag == JwtAlg_ES384) { return "{\"alg\":\"ES384\",\"typ\":\"JWT\"}"; } if (alg.tag == JwtAlg_EdDSA) { return "{\"alg\":\"EdDSA\",\"typ\":\"JWT\"}"; } return "{\"alg\":\"none\",\"typ\":\"JWT\"}"; } String Jwt_Sign(JwtAlg alg, String signingInput, String key) { if (alg.tag == JwtAlg_HS256) { void* buf = Alloc(32); Hmac_Sha256Raw(key, signingInput, buf); String result = bux_base64_encode(((String)buf), 32); Free(buf); return result; } if (alg.tag == JwtAlg_HS384) { void* buf = Alloc(48); Hmac_Sha384Raw(key, signingInput, buf); String result = bux_base64_encode(((String)buf), 48); Free(buf); return result; } if (alg.tag == JwtAlg_HS512) { void* buf = Alloc(64); Hmac_Sha512Raw(key, signingInput, buf); String result = bux_base64_encode(((String)buf), 64); Free(buf); return result; } if (alg.tag == JwtAlg_RS256) { String raw = Rsa_SignSha256(key, signingInput); return bux_base64_encode(raw, ((int)String_Len(raw))); } if (alg.tag == JwtAlg_RS384) { String raw = Rsa_SignSha384(key, signingInput); return bux_base64_encode(raw, ((int)String_Len(raw))); } if (alg.tag == JwtAlg_RS512) { String raw = Rsa_SignSha512(key, signingInput); return bux_base64_encode(raw, ((int)String_Len(raw))); } if (alg.tag == JwtAlg_ES256) { String raw = Ecdsa_SignP256(key, signingInput); return bux_base64_encode(raw, ((int)String_Len(raw))); } if (alg.tag == JwtAlg_ES384) { String raw = Ecdsa_SignP384(key, signingInput); return bux_base64_encode(raw, ((int)String_Len(raw))); } if (alg.tag == JwtAlg_EdDSA) { return Ed25519_Sign(key, signingInput); } return ""; } bool Jwt_Verify(JwtAlg alg, String signingInput, String signatureB64, String key) { if (alg.tag == JwtAlg_HS256) { void* expectBuf = Alloc(32); Hmac_Sha256Raw(key, signingInput, expectBuf); String expectB64 = bux_base64_encode(((String)expectBuf), 32); Free(expectBuf); return String_Eq(expectB64, signatureB64); } if (alg.tag == JwtAlg_HS384) { void* expectBuf = Alloc(48); Hmac_Sha384Raw(key, signingInput, expectBuf); String expectB64 = bux_base64_encode(((String)expectBuf), 48); Free(expectBuf); return String_Eq(expectB64, signatureB64); } if (alg.tag == JwtAlg_HS512) { void* expectBuf = Alloc(64); Hmac_Sha512Raw(key, signingInput, expectBuf); String expectB64 = bux_base64_encode(((String)expectBuf), 64); Free(expectBuf); return String_Eq(expectB64, signatureB64); } if (alg.tag == JwtAlg_RS256) { return Rsa_VerifySha256(key, signingInput, signatureB64); } if (alg.tag == JwtAlg_RS384) { return Rsa_VerifySha384(key, signingInput, signatureB64); } if (alg.tag == JwtAlg_RS512) { return Rsa_VerifySha512(key, signingInput, signatureB64); } if (alg.tag == JwtAlg_ES256) { return Ecdsa_VerifyP256(key, signingInput, signatureB64); } if (alg.tag == JwtAlg_ES384) { return Ecdsa_VerifyP384(key, signingInput, signatureB64); } if (alg.tag == JwtAlg_EdDSA) { return Ed25519_Verify(key, signatureB64, signingInput); } return false; } String Jwt_Encode(String headerJson, String payloadJson, JwtAlg alg, String key) { String headerB64 = Base64URL_Encode(headerJson); String payloadB64 = Base64URL_Encode(payloadJson); String signingInput = String_Concat(headerB64, "."); String signingInputFull = String_Concat(signingInput, payloadB64); String sigB64 = Jwt_Sign(alg, signingInputFull, key); String part1 = String_Concat(signingInputFull, "."); return String_Concat(part1, sigB64); } bool Jwt_Decode(String token, JwtAlg alg, String key, String* headerOut, String* payloadOut) { uint partCount = bux_str_split_count(token, "."); if (partCount != 3) { return false; } String headerB64 = bux_str_split_part(token, ".", 0); String payloadB64 = bux_str_split_part(token, ".", 1); String sigB64 = bux_str_split_part(token, ".", 2); String input = String_Concat(headerB64, "."); String signingInput = String_Concat(input, payloadB64); if (!Jwt_Verify(alg, signingInput, sigB64, key)) { return false; } headerOut[0] = Base64URL_Decode(headerB64); payloadOut[0] = Base64URL_Decode(payloadB64); return true; } String Jwt_EncodeHS256(String payloadJson, String secret) { String header = Jwt_MakeHeader(((JwtAlg){.tag = JwtAlg_HS256})); return Jwt_Encode(header, payloadJson, ((JwtAlg){.tag = JwtAlg_HS256}), secret); } String Jwt_EncodeHS384(String payloadJson, String secret) { String header = Jwt_MakeHeader(((JwtAlg){.tag = JwtAlg_HS384})); return Jwt_Encode(header, payloadJson, ((JwtAlg){.tag = JwtAlg_HS384}), secret); } String Jwt_EncodeHS512(String payloadJson, String secret) { String header = Jwt_MakeHeader(((JwtAlg){.tag = JwtAlg_HS512})); return Jwt_Encode(header, payloadJson, ((JwtAlg){.tag = JwtAlg_HS512}), secret); } String Jwt_EncodeRS256(String payloadJson, String pemPrivateKey) { String header = Jwt_MakeHeader(((JwtAlg){.tag = JwtAlg_RS256})); return Jwt_Encode(header, payloadJson, ((JwtAlg){.tag = JwtAlg_RS256}), pemPrivateKey); } String Jwt_EncodeES256(String payloadJson, String pemPrivateKey) { String header = Jwt_MakeHeader(((JwtAlg){.tag = JwtAlg_ES256})); return Jwt_Encode(header, payloadJson, ((JwtAlg){.tag = JwtAlg_ES256}), pemPrivateKey); } String Jwt_EncodeEdDSA(String payloadJson, String rawPrivKey) { String header = Jwt_MakeHeader(((JwtAlg){.tag = JwtAlg_EdDSA})); return Jwt_Encode(header, payloadJson, ((JwtAlg){.tag = JwtAlg_EdDSA}), rawPrivKey); } String Ecdsa_SignP256(String pemPrivateKey, String data) { int siglen = 0; return bux_ecdsa_sign_p256(pemPrivateKey, ((int)String_Len(pemPrivateKey)), data, ((int)String_Len(data)), &siglen); } String Ecdsa_SignP256Base64(String pemPrivateKey, String data) { String raw = Ecdsa_SignP256(pemPrivateKey, data); return bux_base64_encode(raw, ((int)String_Len(raw))); } bool Ecdsa_VerifyP256(String pemPublicKey, String data, String signature) { int r = bux_ecdsa_verify_p256(pemPublicKey, ((int)String_Len(pemPublicKey)), data, ((int)String_Len(data)), signature, ((int)String_Len(signature))); return r == 1; } bool Ecdsa_VerifyP256Base64(String pemPublicKey, String data, String signatureB64) { int outlen = 0; String sig = bux_base64_decode(signatureB64, ((int)String_Len(signatureB64)), &outlen); return Ecdsa_VerifyP256(pemPublicKey, data, sig); } String Ecdsa_SignP384(String pemPrivateKey, String data) { int siglen = 0; return bux_ecdsa_sign_p384(pemPrivateKey, ((int)String_Len(pemPrivateKey)), data, ((int)String_Len(data)), &siglen); } String Ecdsa_SignP384Base64(String pemPrivateKey, String data) { String raw = Ecdsa_SignP384(pemPrivateKey, data); return bux_base64_encode(raw, ((int)String_Len(raw))); } bool Ecdsa_VerifyP384(String pemPublicKey, String data, String signature) { int r = bux_ecdsa_verify_p384(pemPublicKey, ((int)String_Len(pemPublicKey)), data, ((int)String_Len(data)), signature, ((int)String_Len(signature))); return r == 1; } bool Ecdsa_VerifyP384Base64(String pemPublicKey, String data, String signatureB64) { int outlen = 0; String sig = bux_base64_decode(signatureB64, ((int)String_Len(signatureB64)), &outlen); return Ecdsa_VerifyP384(pemPublicKey, data, sig); } bool Ed25519_Keypair(void* pubKey, void* privKey) { int r = bux_ed25519_keypair(pubKey, privKey); return r == 1; } String Ed25519_KeypairBase64() { void* pubBuf = Alloc(((uint)ED25519_PUBKEY_SIZE)); void* priv = Alloc(((uint)ED25519_PRIVKEY_SIZE)); if (bux_ed25519_keypair(pubBuf, priv) != 1) { Free(pubBuf); Free(priv); return ""; } String pubB64 = bux_base64_encode(((String)pubBuf), ED25519_PUBKEY_SIZE); String privB64 = bux_base64_encode(((String)priv), ED25519_PRIVKEY_SIZE); Free(pubBuf); Free(priv); String pair = String_Concat(pubB64, ":"); return String_Concat(pair, privB64); } String Ed25519_Sign(String privKey, String data) { void* sig = Alloc(((uint)ED25519_SIG_SIZE)); if (bux_ed25519_sign(privKey, data, ((int)String_Len(data)), sig) != 1) { Free(sig); return ""; } return ((String)sig); } String Ed25519_SignBase64(String privKey, String data) { String sig = Ed25519_Sign(privKey, data); if (String_Len(sig) == 0) { return ""; } return bux_base64_encode(sig, ED25519_SIG_SIZE); } bool Ed25519_Verify(String pubKey, String signature, String data) { int r = bux_ed25519_verify(pubKey, signature, data, ((int)String_Len(data))); return r == 1; } bool Ed25519_VerifyBase64(String pubKey, String signatureB64, String data) { int outlen = 0; String sig = bux_base64_decode(signatureB64, ((int)String_Len(signatureB64)), &outlen); if (outlen != ED25519_SIG_SIZE) { return false; } return Ed25519_Verify(pubKey, sig, data); } String Rsa_SignSha256(String pemPrivateKey, String data) { int siglen = 0; return bux_rsa_sign_sha256(pemPrivateKey, ((int)String_Len(pemPrivateKey)), data, ((int)String_Len(data)), &siglen); } String Rsa_SignSha384(String pemPrivateKey, String data) { int siglen = 0; return bux_rsa_sign_sha384(pemPrivateKey, ((int)String_Len(pemPrivateKey)), data, ((int)String_Len(data)), &siglen); } String Rsa_SignSha512(String pemPrivateKey, String data) { int siglen = 0; return bux_rsa_sign_sha512(pemPrivateKey, ((int)String_Len(pemPrivateKey)), data, ((int)String_Len(data)), &siglen); } String Rsa_SignSha256Base64(String pemPrivateKey, String data) { String raw = Rsa_SignSha256(pemPrivateKey, data); return bux_base64_encode(raw, ((int)String_Len(raw))); } String Rsa_SignSha384Base64(String pemPrivateKey, String data) { String raw = Rsa_SignSha384(pemPrivateKey, data); return bux_base64_encode(raw, ((int)String_Len(raw))); } String Rsa_SignSha512Base64(String pemPrivateKey, String data) { String raw = Rsa_SignSha512(pemPrivateKey, data); return bux_base64_encode(raw, ((int)String_Len(raw))); } bool Rsa_VerifySha256(String pemPublicKey, String data, String signature) { int r = bux_rsa_verify_sha256(pemPublicKey, ((int)String_Len(pemPublicKey)), data, ((int)String_Len(data)), signature, ((int)String_Len(signature))); return r == 1; } bool Rsa_VerifySha384(String pemPublicKey, String data, String signature) { int r = bux_rsa_verify_sha384(pemPublicKey, ((int)String_Len(pemPublicKey)), data, ((int)String_Len(data)), signature, ((int)String_Len(signature))); return r == 1; } bool Rsa_VerifySha512(String pemPublicKey, String data, String signature) { int r = bux_rsa_verify_sha512(pemPublicKey, ((int)String_Len(pemPublicKey)), data, ((int)String_Len(data)), signature, ((int)String_Len(signature))); return r == 1; } bool Rsa_VerifySha256Base64(String pemPublicKey, String data, String signatureB64) { int outlen = 0; String sig = bux_base64_decode(signatureB64, ((int)String_Len(signatureB64)), &outlen); return Rsa_VerifySha256(pemPublicKey, data, sig); } bool Rsa_VerifySha384Base64(String pemPublicKey, String data, String signatureB64) { int outlen = 0; String sig = bux_base64_decode(signatureB64, ((int)String_Len(signatureB64)), &outlen); return Rsa_VerifySha384(pemPublicKey, data, sig); } bool Rsa_VerifySha512Base64(String pemPublicKey, String data, String signatureB64) { int outlen = 0; String sig = bux_base64_decode(signatureB64, ((int)String_Len(signatureB64)), &outlen); return Rsa_VerifySha512(pemPublicKey, data, sig); } uint String_Len(String s) { return bux_strlen(s); } bool String_IsNull(String s) { return bux_str_is_null(s) != 0; } bool String_Eq(String a, String b) { return bux_strcmp(a, b) == 0; } String String_Concat(String a, String b) { uint len_a = bux_strlen(a); uint len_b = bux_strlen(b); uint total = len_a + len_b + 1; char8* buf = ((char8*)bux_alloc(total)); bux_strcpy(buf, a); bux_strcat(buf, b); return buf; } String String_Copy(String s) { uint len = bux_strlen(s); char8* buf = ((char8*)bux_alloc(len + 1)); bux_strcpy(buf, s); return buf; } bool String_StartsWith(String s, String prefix) { uint s_len = bux_strlen(s); uint p_len = bux_strlen(prefix); if (p_len > s_len) { return false; } int r = bux_strncmp(s, prefix, p_len); return r == 0; } bool String_EndsWith(String s, String suffix) { uint s_len = bux_strlen(s); uint suf_len = bux_strlen(suffix); if (suf_len > s_len) { return false; } uint start = s_len - suf_len; String tail = bux_str_slice(s, start, suf_len); bool eq = bux_strcmp(tail, suffix) == 0; return eq; } bool String_Contains(String s, String substr) { int r = bux_str_contains(s, substr); return r != 0; } String String_Slice(String s, uint start, uint len) { return bux_str_slice(s, start, len); } String String_Trim(String s) { return bux_str_trim(s); } String String_TrimLeft(String s) { return bux_str_trim_left(s); } String String_TrimRight(String s) { return bux_str_trim_right(s); } String String_FromInt(int64 n) { return bux_int_to_str(n); } int64 String_ToInt(String s) { return bux_str_to_int(s); } StringBuilder StringBuilder_New() { return ((StringBuilder){.handle = bux_sb_new(64)}); } StringBuilder StringBuilder_NewCap(uint cap) { return ((StringBuilder){.handle = bux_sb_new(cap)}); } void StringBuilder_Append(StringBuilder* sb, String s) { bux_sb_append(sb->handle, s); } void StringBuilder_AppendInt(StringBuilder* sb, int64 n) { bux_sb_append_int(sb->handle, n); } void StringBuilder_AppendFloat(StringBuilder* sb, float64 f) { bux_sb_append_float(sb->handle, f); } void StringBuilder_AppendChar(StringBuilder* sb, char8 c) { bux_sb_append_char(sb->handle, c); } String StringBuilder_Build(StringBuilder* sb) { return bux_sb_build(sb->handle); } void StringBuilder_Free(StringBuilder* sb) { bux_sb_free(sb->handle); } uint String_SplitCount(String s, String delim) { return bux_str_split_count(s, delim); } String String_SplitPart(String s, String delim, uint index) { return bux_str_split_part(s, delim, index); } String String_Join2(String a, String b, String sep) { return bux_str_join2(a, b, sep); } String String_Chars(String s, uint index) { return bux_str_slice(s, index, 1); } String String_Find(String haystack, String needle) { return bux_strstr(haystack, needle); } uint String_Offset(String pos, String base) { return bux_str_offset(pos, base); } String String_Replace(String s, String old, String new) { String pos = bux_strstr(s, old); if (String_IsNull(pos)) { return s; } uint oldLen = bux_strlen(old); uint prefixLen = String_Offset(pos, s); String prefix = bux_str_slice(s, 0, prefixLen); String suffix = bux_str_slice(s, prefixLen + oldLen, bux_strlen(s) - prefixLen - oldLen); String temp = String_Concat(prefix, new); String result = String_Concat(temp, suffix); return result; } float64 String_ToFloat(String s) { return bux_str_to_float(s); } String String_FromBool(bool b) { if (b) { return "true"; } return "false"; } String String_FromFloat(float64 f) { return bux_float_to_string(f); } String String_Format1(String pattern, String a0) { return bux_str_format(pattern, a0, "", "", "", "", "", "", ""); } String String_Format2(String pattern, String a0, String a1) { return bux_str_format(pattern, a0, a1, "", "", "", "", "", ""); } String String_Format3(String pattern, String a0, String a1, String a2) { return bux_str_format(pattern, a0, a1, a2, "", "", "", "", ""); } void Channel_SendInt(Channel_int* ch, int value) { bux_channel_send(ch->handle, ((void*)&value)); } int Channel_RecvInt(Channel_int* ch) { int result = 0; bux_channel_recv(ch->handle, ((void*)&result)); return result; } void Channel_SendFloat64(Channel_float64* ch, float64 value) { bux_channel_send(ch->handle, ((void*)&value)); } float64 Channel_RecvFloat64(Channel_float64* ch) { float64 result = 0.0; bux_channel_recv(ch->handle, ((void*)&result)); return result; } int Main() { int x = "hello"; return 0; } extern int g_argc; extern char** g_argv; int main(int argc, char** argv) { g_argc = argc; g_argv = argv; return Main(); }