From 4ba8c7dc48f1f5abc1dcbdcdd5cf8e78b50e3209 Mon Sep 17 00:00:00 2001 From: Shane Bryldt Date: Thu, 5 Oct 2017 05:21:58 -0600 Subject: [PATCH] FS-10690: [libblade] [libks] Cleaned up projects so they build as static libs rather than DLL projects where appropriate. Set all projects that weren't using the right windows CRT library to use DLL based even when statically compiling. Cleaned up some project preprocessor definitions and moved around some preprocessor code to make it simpler. Added ks_sb_t to support an efficient universal string builder. Tested string builder with a temporary REST service exposed by switchblade application. --- libs/libblade/libblade.sln | 70 +----- libs/libblade/libblade.vcxproj | 22 +- libs/libblade/src/blade_restmgr.c | 200 ++++++++++++++++- libs/libblade/src/include/blade_restmgr.h | 5 +- libs/libblade/src/include/blade_types.h | 1 + libs/libblade/switchblade/switchblade.c | 30 +++ libs/libblade/switchblade/switchblade.vcxproj | 19 +- libs/libblade/test/bladec.vcxproj | 4 +- libs/libblade/test/blades.vcxproj | 4 +- libs/libblade/test/testcli.vcxproj | 19 +- libs/libblade/test/testcon.vcxproj | 19 +- libs/libks/libks.vcxproj | 16 +- libs/libks/libks.vcxproj.filters | 6 + libs/libks/src/include/ks.h | 1 + libs/libks/src/include/ks_cJSON.h | 16 ++ libs/libks/src/include/ks_json.h | 12 - libs/libks/src/include/ks_pool.h | 10 + libs/libks/src/include/ks_printf.h | 1 + libs/libks/src/include/ks_sb.h | 65 ++++++ libs/libks/src/ks_printf.c | 10 - libs/libks/src/ks_sb.c | 205 ++++++++++++++++++ libs/libks/src/kws.c | 2 +- libs/win32/civetweb/civetweb.2015.vcxproj | 6 + libs/win32/libconfig/libconfig.2015.vcxproj | 4 +- libs/win32/libsodium/libsodium.2015.vcxproj | 4 +- 25 files changed, 590 insertions(+), 161 deletions(-) create mode 100644 libs/libks/src/include/ks_sb.h create mode 100644 libs/libks/src/ks_sb.c diff --git a/libs/libblade/libblade.sln b/libs/libblade/libblade.sln index 1868c41652..bcce6559b8 100644 --- a/libs/libblade/libblade.sln +++ b/libs/libblade/libblade.sln @@ -17,10 +17,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsodium", "..\win32\libso EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libconfig", "..\win32\libconfig\libconfig.2015.vcxproj", "{1A234565-926D-49B2-83E4-D56E0C38C9F2}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blades", "test\blades.vcxproj", "{636D5B57-FC64-4A18-8D42-54209F8886BD}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bladec", "test\bladec.vcxproj", "{4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "switchblade", "switchblade\switchblade.vcxproj", "{8330E669-77F3-4F70-A275-6F7BABE050A7}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testcli", "test\testcli.vcxproj", "{CF89E839-AB50-4BBB-AC34-0D6232E1EBB5}" @@ -187,8 +183,8 @@ Global {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug DLL|x64.Build.0 = Debug|x64 {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug DLL|x86.ActiveCfg = DebugDLL|Win32 {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug DLL|x86.Build.0 = DebugDLL|Win32 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x64.ActiveCfg = DebugDLL|x64 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x64.Build.0 = DebugDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x64.ActiveCfg = Debug|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x64.Build.0 = Debug|x64 {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x86.ActiveCfg = Debug|Win32 {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x86.Build.0 = Debug|Win32 {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 @@ -199,8 +195,8 @@ Global {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release DLL|x64.Build.0 = Release|x64 {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release DLL|x86.ActiveCfg = ReleaseDLL|Win32 {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release DLL|x86.Build.0 = ReleaseDLL|Win32 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x64.ActiveCfg = ReleaseDLL|x64 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x64.Build.0 = ReleaseDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x64.ActiveCfg = Release|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x64.Build.0 = Release|x64 {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x86.ActiveCfg = Release|Win32 {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x86.Build.0 = Release|Win32 {A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 @@ -211,8 +207,8 @@ Global {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug DLL|x64.Build.0 = Debug|x64 {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug DLL|x86.ActiveCfg = DebugDLL|Win32 {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug DLL|x86.Build.0 = DebugDLL|Win32 - {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug|x64.ActiveCfg = DebugDLL|x64 - {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug|x64.Build.0 = DebugDLL|x64 + {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug|x64.ActiveCfg = Debug|x64 + {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug|x64.Build.0 = Debug|x64 {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug|x86.ActiveCfg = Debug|Win32 {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Debug|x86.Build.0 = Debug|Win32 {1A234565-926D-49B2-83E4-D56E0C38C9F2}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 @@ -223,62 +219,14 @@ Global {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release DLL|x64.Build.0 = Release|x64 {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release DLL|x86.ActiveCfg = ReleaseDLL|Win32 {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release DLL|x86.Build.0 = ReleaseDLL|Win32 - {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release|x64.ActiveCfg = ReleaseDLL|x64 - {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release|x64.Build.0 = ReleaseDLL|x64 + {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release|x64.ActiveCfg = Release|x64 + {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release|x64.Build.0 = Release|x64 {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release|x86.ActiveCfg = Release|Win32 {1A234565-926D-49B2-83E4-D56E0C38C9F2}.Release|x86.Build.0 = Release|Win32 {1A234565-926D-49B2-83E4-D56E0C38C9F2}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 {1A234565-926D-49B2-83E4-D56E0C38C9F2}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 {1A234565-926D-49B2-83E4-D56E0C38C9F2}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 {1A234565-926D-49B2-83E4-D56E0C38C9F2}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.Debug DLL|x64.ActiveCfg = Debug|x64 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.Debug DLL|x64.Build.0 = Debug|x64 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.Debug DLL|x86.ActiveCfg = Debug|Win32 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.Debug DLL|x86.Build.0 = Debug|Win32 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.Debug|x64.ActiveCfg = Debug|x64 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.Debug|x64.Build.0 = Debug|x64 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.Debug|x86.ActiveCfg = Debug|Win32 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.Debug|x86.Build.0 = Debug|Win32 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.DebugDLL|x64.ActiveCfg = Debug|x64 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.DebugDLL|x64.Build.0 = Debug|x64 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.DebugDLL|x86.ActiveCfg = Debug|Win32 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.DebugDLL|x86.Build.0 = Debug|Win32 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.Release DLL|x64.ActiveCfg = Release|x64 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.Release DLL|x64.Build.0 = Release|x64 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.Release DLL|x86.ActiveCfg = Release|Win32 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.Release DLL|x86.Build.0 = Release|Win32 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.Release|x64.ActiveCfg = Release|x64 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.Release|x64.Build.0 = Release|x64 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.Release|x86.ActiveCfg = Release|Win32 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.Release|x86.Build.0 = Release|Win32 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.ReleaseDLL|x64.ActiveCfg = Release|x64 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.ReleaseDLL|x64.Build.0 = Release|x64 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.ReleaseDLL|x86.ActiveCfg = Release|Win32 - {636D5B57-FC64-4A18-8D42-54209F8886BD}.ReleaseDLL|x86.Build.0 = Release|Win32 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.Debug DLL|x64.ActiveCfg = Debug|x64 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.Debug DLL|x64.Build.0 = Debug|x64 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.Debug DLL|x86.ActiveCfg = Debug|Win32 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.Debug DLL|x86.Build.0 = Debug|Win32 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.Debug|x64.ActiveCfg = Debug|x64 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.Debug|x64.Build.0 = Debug|x64 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.Debug|x86.ActiveCfg = Debug|Win32 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.Debug|x86.Build.0 = Debug|Win32 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.DebugDLL|x64.ActiveCfg = Debug|x64 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.DebugDLL|x64.Build.0 = Debug|x64 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.DebugDLL|x86.ActiveCfg = Debug|Win32 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.DebugDLL|x86.Build.0 = Debug|Win32 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.Release DLL|x64.ActiveCfg = Release|x64 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.Release DLL|x64.Build.0 = Release|x64 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.Release DLL|x86.ActiveCfg = Release|Win32 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.Release DLL|x86.Build.0 = Release|Win32 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.Release|x64.ActiveCfg = Release|x64 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.Release|x64.Build.0 = Release|x64 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.Release|x86.ActiveCfg = Release|Win32 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.Release|x86.Build.0 = Release|Win32 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.ReleaseDLL|x64.ActiveCfg = Release|x64 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.ReleaseDLL|x64.Build.0 = Release|x64 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.ReleaseDLL|x86.ActiveCfg = Release|Win32 - {4A70CDA9-AC5B-4818-BCF2-B0DD1B8F5F5F}.ReleaseDLL|x86.Build.0 = Release|Win32 {8330E669-77F3-4F70-A275-6F7BABE050A7}.Debug DLL|x64.ActiveCfg = Debug|x64 {8330E669-77F3-4F70-A275-6F7BABE050A7}.Debug DLL|x64.Build.0 = Debug|x64 {8330E669-77F3-4F70-A275-6F7BABE050A7}.Debug DLL|x86.ActiveCfg = Debug|Win32 @@ -524,6 +472,7 @@ Global {B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Debug DLL|x86.ActiveCfg = Debug|Win32 {B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Debug DLL|x86.Build.0 = Debug|Win32 {B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Debug|x64.ActiveCfg = Debug|Win32 + {B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Debug|x64.Build.0 = Debug|Win32 {B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Debug|x86.ActiveCfg = Debug|Win32 {B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Debug|x86.Build.0 = Debug|Win32 {B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.DebugDLL|x64.ActiveCfg = Release|Win32 @@ -535,6 +484,7 @@ Global {B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Release DLL|x86.ActiveCfg = Release|Win32 {B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Release DLL|x86.Build.0 = Release|Win32 {B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Release|x64.ActiveCfg = Release|Win32 + {B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Release|x64.Build.0 = Release|Win32 {B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Release|x86.ActiveCfg = Release|Win32 {B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.Release|x86.Build.0 = Release|Win32 {B1E7E876-347F-4DC9-9BEA-D1AFBD9DFF8A}.ReleaseDLL|x64.ActiveCfg = Release|Win32 diff --git a/libs/libblade/libblade.vcxproj b/libs/libblade/libblade.vcxproj index 9cc352f2e6..3420ccef22 100644 --- a/libs/libblade/libblade.vcxproj +++ b/libs/libblade/libblade.vcxproj @@ -37,13 +37,13 @@ Unicode - DynamicLibrary + StaticLibrary true v140 Unicode - DynamicLibrary + StaticLibrary false v140 Unicode @@ -163,7 +163,7 @@ $(SolutionDir)..\win32\openssl\include;$(SolutionDir)..\win32\openssl\include_x64;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBKS_EXPORTS;CJSON_EXPORT_SYMBOLS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;KS_DECLARE_STATIC;%(PreprocessorDefinitions) EditAndContinue EnableAllWarnings true @@ -172,6 +172,7 @@ true false true + MultiThreadedDebugDLL Windows @@ -182,12 +183,13 @@ $(SolutionDir)..\win32\openssl\include;$(SolutionDir)..\win32\openssl\include_x64;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBKS_EXPORTS;CJSON_EXPORT_SYMBOLS;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;KS_DECLARE_STATIC;%(PreprocessorDefinitions) EnableAllWarnings true true 4711;4574;4100;4127;4668;4255;4706;4710;4820;4090;4702;4456;4242;4457;4459;4244;4324;4204;4388;4245;4267 true + MultiThreadedDLL Windows @@ -242,12 +244,6 @@ - - {0a11689c-db6a-4bf6-97b2-ad32db863fbd} - - - {8f5e5d77-d269-4665-9e27-1045da6cf0d8} - {70d178d8-1100-4152-86c0-809a91cff832} @@ -260,12 +256,6 @@ {a185b162-6cb6-4502-b03f-b56f7699a8d9} - - {d331904d-a00a-4694-a5a3-fcff64ab5dbe} - - - {b4b62169-5ad4-4559-8707-3d933ac5db39} - {8d04b550-d240-4a44-8a18-35da3f7038d9} diff --git a/libs/libblade/src/blade_restmgr.c b/libs/libblade/src/blade_restmgr.c index f6d3df0905..9c241e3ef7 100644 --- a/libs/libblade/src/blade_restmgr.c +++ b/libs/libblade/src/blade_restmgr.c @@ -33,6 +33,9 @@ #include "blade.h" +#define BLADE_RESTMGR_SERVICE_CAPTURE_MAX 10 +#define BLADE_RESTMGR_SERVICE_CAPTURE_VECTORS (BLADE_RESTMGR_SERVICE_CAPTURE_MAX * 3) // @note Last third of this is workspace + typedef struct blade_restmgr_config_s { ks_bool_t enabled; @@ -47,8 +50,46 @@ struct blade_restmgr_s { void *data; struct mg_context *context; + + ks_hash_t *services; }; +typedef struct blade_restmgr_service_s { + pcre *compiled; + pcre_extra *extra; + const char *action; + blade_restmgr_service_callback_t callback; +} blade_restmgr_service_t; + +static void blade_restmgr_service_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type) +{ + blade_restmgr_service_t *brestmgrs = (blade_restmgr_service_t *)ptr; + + ks_assert(brestmgrs); + + switch (action) { + case KS_MPCL_ANNOUNCE: + break; + case KS_MPCL_TEARDOWN: + if (brestmgrs->compiled) { + pcre_free(brestmgrs->compiled); + brestmgrs->compiled = NULL; + } + if (brestmgrs->extra) { +#ifdef PCRE_CONFIG_JIT + pcre_free_study(brestmgrs->extra); +#else + pcre_free(brestmgrs->extra); +#endif + brestmgrs->extra = NULL; + } + if (brestmgrs->action) ks_pool_free(&brestmgrs->action); + break; + case KS_MPCL_DESTROY: + break; + } +} + int blade_restmgr_handle_begin_request(struct mg_connection *conn); void blade_restmgr_handle_end_request(const struct mg_connection *conn, int reply_status_code); int blade_restmgr_handle_log_message(const struct mg_connection *conn, const char *message); @@ -95,6 +136,9 @@ KS_DECLARE(ks_status_t) blade_restmgr_create(blade_restmgr_t **brestmgrP, blade_ ks_hash_create(&brestmgr->config.options, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, pool); ks_assert(brestmgr->config.options); + ks_hash_create(&brestmgr->services, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool); + ks_assert(brestmgr->services); + ks_pool_set_cleanup(brestmgr, NULL, blade_restmgr_cleanup); *brestmgrP = brestmgr; @@ -254,7 +298,7 @@ KS_DECLARE(ks_status_t) blade_restmgr_startup(blade_restmgr_t *brestmgr, config_ } options[index++] = NULL; - brestmgr->context = mg_start(&callbacks, brestmgr->data, options); + brestmgr->context = mg_start(&callbacks, brestmgr, options); ks_pool_free(&options); @@ -281,6 +325,13 @@ KS_DECLARE(blade_handle_t *) blade_restmgr_handle_get(blade_restmgr_t *brestmgr) return brestmgr->handle; } +KS_DECLARE(void *) blade_restmgr_data_get(blade_restmgr_t *brestmgr) +{ + ks_assert(brestmgr); + + return brestmgr->data; +} + KS_DECLARE(ks_status_t) blade_restmgr_data_set(blade_restmgr_t *brestmgr, void *data) { ks_assert(brestmgr); @@ -290,14 +341,157 @@ KS_DECLARE(ks_status_t) blade_restmgr_data_set(blade_restmgr_t *brestmgr, void * return KS_STATUS_SUCCESS; } +KS_DECLARE(ks_status_t) blade_restmgr_service_add(blade_restmgr_t *brestmgr, const char *action, const char *route, blade_restmgr_service_callback_t callback) +{ + ks_status_t ret = KS_STATUS_SUCCESS; + ks_pool_t *pool = NULL; + char *key = NULL; + blade_restmgr_service_t *service = NULL; + const char *errString = NULL; + int errOffset = 0; + + ks_assert(brestmgr); + ks_assert(route); + ks_assert(callback); + + pool = ks_pool_get(brestmgr); + + key = ks_psprintf(pool, "%s:%s", action, route); + + ks_hash_write_lock(brestmgr->services); + + if ((service = (blade_restmgr_service_t *)ks_hash_remove(brestmgr->services, (void *)key)) != NULL) { + ks_log(KS_LOG_DEBUG, "Service Removed: %s\n", key); + ks_pool_free(&service); + } + + service = ks_pool_alloc(pool, sizeof(blade_restmgr_service_t)); + ks_pool_set_cleanup(service, NULL, blade_restmgr_service_cleanup); + + service->callback = callback; + service->action = ks_pstrdup(pool, action); + + service->compiled = pcre_compile(route, 0, &errString, &errOffset, NULL); + if (service->compiled == NULL) { + ks_log(KS_LOG_DEBUG, "Could not compile '%s': %s\n", route, errString); + ret = KS_STATUS_FAIL; + goto done; + } + + service->extra = pcre_study(service->compiled, 0, &errString); + if (errString != NULL) { + ks_log(KS_LOG_DEBUG, "Could not study '%s': %s\n", route, errString); + ret = KS_STATUS_FAIL; + goto done; + } + + ks_hash_insert(brestmgr->services, (void *)key, (void *)service); + + ks_log(KS_LOG_DEBUG, "Service Added: %s\n", key); + +done: + ks_hash_write_unlock(brestmgr->services); + + return ret; +} + +KS_DECLARE(ks_status_t) blade_restmgr_service_remove(blade_restmgr_t *brestmgr, const char *action, const char *route) +{ + ks_pool_t *pool = NULL; + const char *key = NULL; + blade_restmgr_service_t *service = NULL; + + ks_assert(brestmgr); + ks_assert(route); + + pool = ks_pool_get(brestmgr); + + key = ks_psprintf(pool, "%s:%s", action, route); + + if ((service = (blade_restmgr_service_t *)ks_hash_remove(brestmgr->services, (void *)key)) != NULL) { + ks_log(KS_LOG_DEBUG, "Service Removed: %s\n", key); + ks_pool_free(&service); + } + + ks_pool_free(&key); + + return KS_STATUS_SUCCESS; +} + int blade_restmgr_handle_begin_request(struct mg_connection *conn) { - const struct mg_request_info *info = mg_get_request_info(conn); + int ret = 0; + blade_restmgr_t *brestmgr = NULL; + const struct mg_request_info *info = NULL; + int execRet = 0; + int captureVectors[BLADE_RESTMGR_SERVICE_CAPTURE_VECTORS]; + + info = mg_get_request_info(conn); ks_log(KS_LOG_DEBUG, "Request for: %s on %s\n", info->request_uri, info->request_method); - return 0; + brestmgr = (blade_restmgr_t *)info->user_data; + + ks_hash_read_lock(brestmgr->services); + + for (ks_hash_iterator_t *it = ks_hash_first(brestmgr->services, KS_UNLOCKED); it; it = ks_hash_next(&it)) { + const char *key = NULL; + blade_restmgr_service_t *value = NULL; + + ks_hash_this(it, (const void **)&key, NULL, (void **)&value); + + // @todo could optimize this to provide a separate hash for each action typed, keyed in a top level hash by the request_method/action string + if (ks_safe_strcasecmp(value->action, info->request_method)) continue; + + execRet = pcre_exec(value->compiled, + value->extra, + info->request_uri, + strlen(info->request_uri), + 0, // Offset + 0, // Options + captureVectors, + BLADE_RESTMGR_SERVICE_CAPTURE_VECTORS); + + if (execRet < 0) { + switch (execRet) { + case PCRE_ERROR_NOMATCH: continue; + case PCRE_ERROR_NULL: ks_log(KS_LOG_DEBUG, "Something was null\n"); break; + case PCRE_ERROR_BADOPTION: ks_log(KS_LOG_DEBUG, "A bad option was passed\n"); break; + case PCRE_ERROR_BADMAGIC: ks_log(KS_LOG_DEBUG, "Magic number bad (compile corrupt?)\n"); break; + case PCRE_ERROR_UNKNOWN_NODE: ks_log(KS_LOG_DEBUG, "Something kooky in the compile\n"); break; + case PCRE_ERROR_NOMEMORY: ks_log(KS_LOG_DEBUG, "Ran out of memory\n"); break; + default: ks_log(KS_LOG_DEBUG, "Unknown error\n"); break; + } + ret = 500; + goto done; + } else { + const char **captures = NULL; + + if (execRet == 0) { + ks_log(KS_LOG_DEBUG, "Too many substrings were found to fit in capture vectors!\n"); + ret = 500; + goto done; + } + + if (pcre_get_substring_list(info->request_uri, captureVectors, execRet, &captures) != 0) { + ks_log(KS_LOG_DEBUG, "Cannot get substring list!\n"); + ret = 500; + goto done; + } + + ret = value->callback(brestmgr, conn, captures); + + pcre_free_substring_list(captures); + //ret = 200; + goto done; + } + } + +done: + ks_hash_read_unlock(brestmgr->services); + + return ret; } void blade_restmgr_handle_end_request(const struct mg_connection *conn, int reply_status_code) diff --git a/libs/libblade/src/include/blade_restmgr.h b/libs/libblade/src/include/blade_restmgr.h index c8ee65ee56..87b5e9aa7d 100644 --- a/libs/libblade/src/include/blade_restmgr.h +++ b/libs/libblade/src/include/blade_restmgr.h @@ -41,7 +41,10 @@ KS_DECLARE(ks_status_t) blade_restmgr_destroy(blade_restmgr_t **brestmgrP); KS_DECLARE(ks_status_t) blade_restmgr_startup(blade_restmgr_t *brestmgr, config_setting_t *config); KS_DECLARE(ks_status_t) blade_restmgr_shutdown(blade_restmgr_t *brestmgr); KS_DECLARE(blade_handle_t *) blade_restmgr_handle_get(blade_restmgr_t *brestmgr); -KS_DECLARE(ks_status_t) blade_restmgr_data_set(blade_restmgr_t *brestmgr, void *data); // @note must use before calling startup +KS_DECLARE(void *) blade_restmgr_data_get(blade_restmgr_t *brestmgr); +KS_DECLARE(ks_status_t) blade_restmgr_data_set(blade_restmgr_t *brestmgr, void *data); +KS_DECLARE(ks_status_t) blade_restmgr_service_add(blade_restmgr_t *brestmgr, const char *action, const char *route, blade_restmgr_service_callback_t callback); +KS_DECLARE(ks_status_t) blade_restmgr_service_remove(blade_restmgr_t *brestmgr, const char *action, const char *route); KS_END_EXTERN_C #endif diff --git a/libs/libblade/src/include/blade_types.h b/libs/libblade/src/include/blade_types.h index ba44e63792..7e6f960235 100644 --- a/libs/libblade/src/include/blade_types.h +++ b/libs/libblade/src/include/blade_types.h @@ -67,6 +67,7 @@ typedef struct blade_restmgr_s blade_restmgr_t; typedef ks_bool_t (*blade_rpc_request_callback_t)(blade_rpc_request_t *brpcreq, void *data); typedef ks_bool_t (*blade_rpc_response_callback_t)(blade_rpc_response_t *brpcres, void *data); +typedef int (*blade_restmgr_service_callback_t)(blade_restmgr_t *brestmgr, struct mg_connection *conn, const char **captures); typedef enum { BLADE_CONNECTION_STATE_NONE, diff --git a/libs/libblade/switchblade/switchblade.c b/libs/libblade/switchblade/switchblade.c index 8a62c3fed3..e18dff0b80 100644 --- a/libs/libblade/switchblade/switchblade.c +++ b/libs/libblade/switchblade/switchblade.c @@ -7,6 +7,7 @@ ks_bool_t g_shutdown = KS_FALSE; void loop(blade_handle_t *bh); void process_console_input(blade_handle_t *bh, char *line); +int rest_service_test(blade_restmgr_t *brestmgr, struct mg_connection *conn, const char **captures); typedef void(*command_callback)(blade_handle_t *bh, char *args); @@ -54,6 +55,8 @@ int main(int argc, char **argv) return EXIT_FAILURE; } + blade_restmgr_service_add(blade_handle_restmgr_get(bh), "GET", "/test/(\\d+)", rest_service_test); + if (blade_handle_startup(bh, config_blade) != KS_STATUS_SUCCESS) { ks_log(KS_LOG_ERROR, "Blade startup failed\n"); return EXIT_FAILURE; @@ -134,6 +137,33 @@ void command_quit(blade_handle_t *bh, char *args) g_shutdown = KS_TRUE; } +int rest_service_test(blade_restmgr_t *brestmgr, struct mg_connection *conn, const char **captures) +{ + const struct mg_request_info *info = NULL; + ks_sb_t *sb = NULL; + + ks_sb_create(&sb, NULL, 0); + + info = mg_get_request_info(conn); + + ks_sb_printf(sb, "Method: %s\n", info->request_method); + + for (int i = 0; captures[i]; ++i) ks_sb_printf(sb, "Capture #%d: %s\n", i, captures[i]); + + mg_printf(conn, + "HTTP/1.1 200 OK\r\n" + "Content-Length: %lu\r\n" + "Content-Type: text/plain\r\n" + "Connection: close\r\n\r\n", + ks_sb_length(sb)); + + mg_write(conn, ks_sb_cstr(sb), ks_sb_length(sb)); + + ks_sb_destroy(&sb); + + return 200; +} + /* For Emacs: * Local Variables: diff --git a/libs/libblade/switchblade/switchblade.vcxproj b/libs/libblade/switchblade/switchblade.vcxproj index 8d994e6f21..de2fb48c5f 100644 --- a/libs/libblade/switchblade/switchblade.vcxproj +++ b/libs/libblade/switchblade/switchblade.vcxproj @@ -139,16 +139,18 @@ Level3 Disabled - _CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;KS_DECLARE_STATIC;%(PreprocessorDefinitions) true $(SolutionDir)..\win32\openssl\include;$(SolutionDir)..\win32\openssl\include_x64;../src/include;.;%(AdditionalIncludeDirectories) 4090 true false + MultiThreadedDebugDLL Console true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;rpcrt4.lib;winmm.lib;%(AdditionalDependencies) @@ -197,21 +199,6 @@ - - {70d178d8-1100-4152-86c0-809a91cff832} - - - {1a234565-926d-49b2-83e4-d56e0c38c9f2} - - - {a185b162-6cb6-4502-b03f-b56f7699a8d9} - - - {d331904d-a00a-4694-a5a3-fcff64ab5dbe} - - - {b4b62169-5ad4-4559-8707-3d933ac5db39} - {a89d6d18-6203-4149-9051-f8e798e7a3e7} diff --git a/libs/libblade/test/bladec.vcxproj b/libs/libblade/test/bladec.vcxproj index 715e3641a9..5bf53cfb87 100644 --- a/libs/libblade/test/bladec.vcxproj +++ b/libs/libblade/test/bladec.vcxproj @@ -139,16 +139,18 @@ Level3 Disabled - _CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;KS_DECLARE_STATIC;%(PreprocessorDefinitions) true $(SolutionDir)..\win32\openssl\include;$(SolutionDir)..\win32\openssl\include_x64;../src/include;.;%(AdditionalIncludeDirectories) 4090 true false + MultiThreadedDebug Console true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;rpcrt4.lib;winmm.lib;%(AdditionalDependencies) diff --git a/libs/libblade/test/blades.vcxproj b/libs/libblade/test/blades.vcxproj index a9f48e92da..d98294e8de 100644 --- a/libs/libblade/test/blades.vcxproj +++ b/libs/libblade/test/blades.vcxproj @@ -139,16 +139,18 @@ Level3 Disabled - _CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;KS_DECLARE_STATIC;%(PreprocessorDefinitions) true $(SolutionDir)..\win32\openssl\include;$(SolutionDir)..\win32\openssl\include_x64;../src/include;.;%(AdditionalIncludeDirectories) 4090 true false + MultiThreadedDebug Console true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;rpcrt4.lib;winmm.lib;%(AdditionalDependencies) diff --git a/libs/libblade/test/testcli.vcxproj b/libs/libblade/test/testcli.vcxproj index e86abfdb1c..381d842a12 100644 --- a/libs/libblade/test/testcli.vcxproj +++ b/libs/libblade/test/testcli.vcxproj @@ -139,16 +139,18 @@ Level3 Disabled - _CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;KS_DECLARE_STATIC;%(PreprocessorDefinitions) true $(SolutionDir)..\win32\openssl\include;$(SolutionDir)..\win32\openssl\include_x64;../src/include;.;%(AdditionalIncludeDirectories) 4090 true false + MultiThreadedDebugDLL Console true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;rpcrt4.lib;winmm.lib;%(AdditionalDependencies) @@ -198,21 +200,6 @@ - - {70d178d8-1100-4152-86c0-809a91cff832} - - - {1a234565-926d-49b2-83e4-d56e0c38c9f2} - - - {a185b162-6cb6-4502-b03f-b56f7699a8d9} - - - {d331904d-a00a-4694-a5a3-fcff64ab5dbe} - - - {b4b62169-5ad4-4559-8707-3d933ac5db39} - {a89d6d18-6203-4149-9051-f8e798e7a3e7} diff --git a/libs/libblade/test/testcon.vcxproj b/libs/libblade/test/testcon.vcxproj index 8740d494ea..ffa9af660d 100644 --- a/libs/libblade/test/testcon.vcxproj +++ b/libs/libblade/test/testcon.vcxproj @@ -139,16 +139,18 @@ Level3 Disabled - _CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;KS_DECLARE_STATIC;%(PreprocessorDefinitions) true $(SolutionDir)..\win32\openssl\include;$(SolutionDir)..\win32\openssl\include_x64;../src/include;.;%(AdditionalIncludeDirectories) 4090 true false + MultiThreadedDebugDLL Console true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;rpcrt4.lib;winmm.lib;%(AdditionalDependencies) @@ -198,21 +200,6 @@ - - {70d178d8-1100-4152-86c0-809a91cff832} - - - {1a234565-926d-49b2-83e4-d56e0c38c9f2} - - - {a185b162-6cb6-4502-b03f-b56f7699a8d9} - - - {d331904d-a00a-4694-a5a3-fcff64ab5dbe} - - - {b4b62169-5ad4-4559-8707-3d933ac5db39} - {a89d6d18-6203-4149-9051-f8e798e7a3e7} diff --git a/libs/libks/libks.vcxproj b/libs/libks/libks.vcxproj index 654341272b..39d3cf7eeb 100644 --- a/libs/libks/libks.vcxproj +++ b/libs/libks/libks.vcxproj @@ -37,13 +37,13 @@ Unicode - DynamicLibrary + StaticLibrary true v140 Unicode - DynamicLibrary + StaticLibrary false v140 Unicode @@ -147,7 +147,7 @@ $(SolutionDir)..\win32\openssl\include;$(SolutionDir)..\win32\openssl\include_x64;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBKS_EXPORTS;CJSON_EXPORT_SYMBOLS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;KS_DECLARE_STATIC;%(PreprocessorDefinitions) EditAndContinue EnableAllWarnings true @@ -156,22 +156,28 @@ true false true + MultiThreadedDebugDLL Windows Debug Rpcrt4.lib;Crypt32.lib;%(AdditionalDependencies) + + + + $(SolutionDir)..\win32\openssl\include;$(SolutionDir)..\win32\openssl\include_x64;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBKS_EXPORTS;CJSON_EXPORT_SYMBOLS;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;KS_DECLARE_STATIC;%(PreprocessorDefinitions) EnableAllWarnings true true 4711;4574;4100;4127;4668;4255;4706;4710;4820;4090;4702 true + MultiThreadedDLL Windows @@ -199,6 +205,7 @@ + @@ -230,6 +237,7 @@ + diff --git a/libs/libks/libks.vcxproj.filters b/libs/libks/libks.vcxproj.filters index d76a361ee7..9e280a5cbc 100644 --- a/libs/libks/libks.vcxproj.filters +++ b/libs/libks/libks.vcxproj.filters @@ -102,6 +102,9 @@ Source Files + + Source Files + @@ -197,5 +200,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/libs/libks/src/include/ks.h b/libs/libks/src/include/ks.h index 61315edee4..4965a50a95 100644 --- a/libs/libks/src/include/ks.h +++ b/libs/libks/src/include/ks.h @@ -144,6 +144,7 @@ KS_DECLARE(void) ks_random_string(char *buf, uint16_t len, char *set); #include "ks_acl.h" #include "ks_base64.h" #include "ks_time.h" +#include "ks_sb.h" KS_END_EXTERN_C diff --git a/libs/libks/src/include/ks_cJSON.h b/libs/libks/src/include/ks_cJSON.h index 37366f9e28..2909b713d6 100644 --- a/libs/libks/src/include/ks_cJSON.h +++ b/libs/libks/src/include/ks_cJSON.h @@ -23,6 +23,22 @@ #ifndef cJSON__h #define cJSON__h +#ifdef KS_EXPORTS +#ifndef CJSON_EXPORT_SYMBOLS +#define CJSON_EXPORT_SYMBOLS 1 +#endif +#else +#ifndef CJSON_HIDE_SYMBOLS +#define CJSON_HIDE_SYMBOLS 1 +#endif +#endif + +#ifdef KS_API_VISIBILITY +#ifndef CJSON_API_VISIBILITY +#define CJSON_API_VISIBILITY 1 +#endif +#endif + #ifdef __cplusplus extern "C" { diff --git a/libs/libks/src/include/ks_json.h b/libs/libks/src/include/ks_json.h index 7abd1d1f56..cafc9ec3dc 100644 --- a/libs/libks/src/include/ks_json.h +++ b/libs/libks/src/include/ks_json.h @@ -23,18 +23,6 @@ #ifndef KS_JSON__h #define KS_JSON__h -#ifdef KS_EXPORTS -#ifndef CJSON_EXPORT_SYMBOLS -#define CJSON_EXPORT_SYMBOLS 1 -#endif -#endif - -#ifdef KS_API_VISIBILITY -#ifndef CJSON_API_VISIBILITY -#define CJSON_API_VISIBILITY 1 -#endif -#endif - #ifdef __cplusplus extern "C" { diff --git a/libs/libks/src/include/ks_pool.h b/libs/libks/src/include/ks_pool.h index 6b16337a16..00c65ccb43 100644 --- a/libs/libks/src/include/ks_pool.h +++ b/libs/libks/src/include/ks_pool.h @@ -48,6 +48,16 @@ typedef enum { #define KS_POOL_FUNC_INCREF 7 /* reference count incremented */ #define KS_POOL_FUNC_DECREF 8 /* reference count decremented */ + /* + ** On machines with a small stack size, you can redefine the + ** KS_PRINT_BUF_SIZE to be less than 350. But beware - for + ** smaller values some %f conversions may go into an infinite loop. + */ +#ifndef KS_PRINT_BUF_SIZE +# define KS_PRINT_BUF_SIZE 350 +#endif +#define etBUFSIZE KS_PRINT_BUF_SIZE /* Size of the output buffer */ + /* * void ks_pool_log_func_t * diff --git a/libs/libks/src/include/ks_printf.h b/libs/libks/src/include/ks_printf.h index 8e9f975246..77ce110313 100644 --- a/libs/libks/src/include/ks_printf.h +++ b/libs/libks/src/include/ks_printf.h @@ -60,6 +60,7 @@ KS_BEGIN_EXTERN_C */ KS_DECLARE(char *) ks_mprintf(const char *zFormat, ...); KS_DECLARE(char *) ks_vmprintf(const char *zFormat, va_list ap); +KS_DECLARE(char *) ks_vsnprintfv(char *zBuf, int n, const char *zFormat, va_list ap); KS_DECLARE(char *) ks_snprintfv(char *zBuf, int n, const char *zFormat, ...); KS_DECLARE(char *) ks_vsnprintf(char *zbuf, int n, const char *zFormat, va_list ap); KS_DECLARE(char *) ks_vpprintf(ks_pool_t *pool, const char *zFormat, va_list ap); diff --git a/libs/libks/src/include/ks_sb.h b/libs/libks/src/include/ks_sb.h new file mode 100644 index 0000000000..b9b5f1863f --- /dev/null +++ b/libs/libks/src/include/ks_sb.h @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2017, Shane Bryldt +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* * Neither the name of the original author; nor the names of any contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef __KS_SB_H__ +#define __KS_SB_H__ + +#include "ks.h" + +KS_BEGIN_EXTERN_C + +typedef struct ks_sb_s ks_sb_t; + +KS_DECLARE(ks_status_t) ks_sb_create(ks_sb_t **sbP, ks_pool_t *pool, ks_size_t preallocated); +KS_DECLARE(ks_status_t) ks_sb_destroy(ks_sb_t **sbP); +KS_DECLARE(const char *) ks_sb_cstr(ks_sb_t *sb); +KS_DECLARE(ks_size_t) ks_sb_length(ks_sb_t *sb); +KS_DECLARE(ks_status_t) ks_sb_accommodate(ks_sb_t *sb, ks_size_t len); +KS_DECLARE(ks_status_t) ks_sb_append(ks_sb_t *sb, const char *str); +KS_DECLARE(ks_status_t) ks_sb_append_ex(ks_sb_t *sb, const char *str, ks_size_t len); +KS_DECLARE(ks_status_t) ks_sb_printf(ks_sb_t *sb, const char *fmt, ...); + +KS_END_EXTERN_C + +#endif + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ diff --git a/libs/libks/src/ks_printf.c b/libs/libks/src/ks_printf.c index d2b86071d3..ea5e09fc1d 100644 --- a/libs/libks/src/ks_printf.c +++ b/libs/libks/src/ks_printf.c @@ -184,16 +184,6 @@ static int et_getdigit(LONGDOUBLE_TYPE * val, int *cnt) } #endif /* KS_OMIT_FLOATING_POINT */ -/* -** On machines with a small stack size, you can redefine the -** KS_PRINT_BUF_SIZE to be less than 350. But beware - for -** smaller values some %f conversions may go into an infinite loop. -*/ -#ifndef KS_PRINT_BUF_SIZE -# define KS_PRINT_BUF_SIZE 350 -#endif -#define etBUFSIZE KS_PRINT_BUF_SIZE /* Size of the output buffer */ - /* ** The root program. All variations call this core. ** diff --git a/libs/libks/src/ks_sb.c b/libs/libks/src/ks_sb.c new file mode 100644 index 0000000000..acdbb594c0 --- /dev/null +++ b/libs/libks/src/ks_sb.c @@ -0,0 +1,205 @@ +/* +* Copyright (c) 2017, Shane Bryldt +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* * Neither the name of the original author; nor the names of any contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "ks.h" +#include "ks_sb.h" + +struct ks_sb_s { + ks_bool_t pool_owner; + char *data; + ks_size_t size; + ks_size_t used; +}; + +static void ks_sb_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type) +{ + ks_sb_t *sb = (ks_sb_t *)ptr; + + switch(action) { + case KS_MPCL_ANNOUNCE: + break; + case KS_MPCL_TEARDOWN: + if (!sb->pool_owner && sb->data) ks_pool_free(&sb->data); + break; + case KS_MPCL_DESTROY: + break; + } + +} + +KS_DECLARE(ks_status_t) ks_sb_create(ks_sb_t **sbP, ks_pool_t *pool, ks_size_t preallocated) +{ + ks_sb_t *sb = NULL; + ks_bool_t pool_owner = KS_FALSE; + + ks_assert(sbP); + + if ((pool_owner = !pool)) ks_pool_open(&pool); + if (preallocated == 0) preallocated = KS_PRINT_BUF_SIZE * 2; + + sb = ks_pool_alloc(pool, sizeof(ks_sb_t)); + sb->pool_owner = pool_owner; + sb->data = ks_pool_alloc(pool, preallocated); + sb->size = preallocated; + sb->used = 1; + + ks_pool_set_cleanup(sb, NULL, ks_sb_cleanup); + + *sbP = sb; + + return KS_STATUS_SUCCESS; +} + +KS_DECLARE(ks_status_t) ks_sb_destroy(ks_sb_t **sbP) +{ + ks_sb_t *sb = NULL; + + ks_assert(sbP); + ks_assert(*sbP); + + sb = *sbP; + + if (sb->pool_owner) { + ks_pool_t *pool = ks_pool_get(sb); + ks_pool_close(&pool); + } else ks_pool_free(sbP); + + return KS_STATUS_SUCCESS; +} + +KS_DECLARE(const char *) ks_sb_cstr(ks_sb_t *sb) +{ + ks_assert(sb); + return sb->data; +} + +KS_DECLARE(ks_size_t) ks_sb_length(ks_sb_t *sb) +{ + ks_assert(sb); + return sb->used - 1; +} + +KS_DECLARE(ks_status_t) ks_sb_accommodate(ks_sb_t *sb, ks_size_t len) +{ + ks_status_t ret = KS_STATUS_SUCCESS; + + ks_assert(sb); + + if (len == 0) goto done; + + if ((sb->used + len) > sb->size) { + ks_size_t needed = (sb->used + len) - sb->size; + if (needed < KS_PRINT_BUF_SIZE) needed = KS_PRINT_BUF_SIZE; + sb->size += needed; + if (!sb->data) sb->data = ks_pool_alloc(ks_pool_get(sb), sb->size); + else { + sb->data = ks_pool_resize(sb->data, sb->size); + if (!sb->data) ret = KS_STATUS_FAIL; + } + } + +done: + return KS_STATUS_SUCCESS; +} + +KS_DECLARE(ks_status_t) ks_sb_append(ks_sb_t *sb, const char *str) +{ + ks_status_t ret = KS_STATUS_SUCCESS; + + ks_assert(sb); + + if (str) ret = ks_sb_append_ex(sb, str, strlen(str)); + + return ret; +} + +KS_DECLARE(ks_status_t) ks_sb_append_ex(ks_sb_t *sb, const char *str, ks_size_t len) +{ + ks_status_t ret = KS_STATUS_SUCCESS; + + ks_assert(sb); + + if (!str || len == 0) goto done; + + if (ks_sb_accommodate(sb, len) != KS_STATUS_SUCCESS) { + ret = KS_STATUS_FAIL; + goto done; + } + + memcpy(sb->data + (sb->used - 1), str, len + 1); + sb->used += len; + +done: + + return ret; +} + +KS_DECLARE(ks_status_t) ks_sb_printf(ks_sb_t *sb, const char *fmt, ...) +{ + ks_status_t ret = KS_STATUS_SUCCESS; + va_list ap; + ks_size_t used = 0; + char *result = NULL; + + ks_assert(sb); + ks_assert(fmt); + + used = sb->used - 1; + + if (ks_sb_accommodate(sb, KS_PRINT_BUF_SIZE) != KS_STATUS_SUCCESS) { + ret = KS_STATUS_FAIL; + goto done; + } + + va_start(ap, fmt); + result = ks_vsnprintfv(sb->data + used, (int)(sb->size - used), fmt, ap); + va_end(ap); + + sb->used += strlen(result); + +done: + return ret; +} + + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ + diff --git a/libs/libks/src/kws.c b/libs/libks/src/kws.c index fed6668ce9..a88275cf9e 100644 --- a/libs/libks/src/kws.c +++ b/libs/libks/src/kws.c @@ -1041,7 +1041,7 @@ KS_DECLARE(ks_ssize_t) kws_read_frame(kws_t *kws, kws_opcode_t *oc, uint8_t **da u64 = (uint64_t *) kws->payload; kws->payload += 8; - kws->plen = ntoh64(*u64); + kws->plen = (ks_ssize_t)ntoh64(*u64); } else if (kws->plen == 126) { uint16_t *u16; diff --git a/libs/win32/civetweb/civetweb.2015.vcxproj b/libs/win32/civetweb/civetweb.2015.vcxproj index 465059aa67..d8a454de55 100644 --- a/libs/win32/civetweb/civetweb.2015.vcxproj +++ b/libs/win32/civetweb/civetweb.2015.vcxproj @@ -140,6 +140,12 @@ + + {0a11689c-db6a-4bf6-97b2-ad32db863fbd} + + + {8f5e5d77-d269-4665-9e27-1045da6cf0d8} + {b9b7455d-f109-42bd-ad0a-98489b53fcf3} diff --git a/libs/win32/libconfig/libconfig.2015.vcxproj b/libs/win32/libconfig/libconfig.2015.vcxproj index 65a89160b8..dd881d8bba 100644 --- a/libs/win32/libconfig/libconfig.2015.vcxproj +++ b/libs/win32/libconfig/libconfig.2015.vcxproj @@ -209,7 +209,7 @@ Disabled WIN32;_DEBUG;%(PreprocessorDefinitions) 4244;%(DisableSpecificWarnings) - MultiThreadedDebug + MultiThreadedDebugDLL /arch:AVX %(AdditionalOptions) false @@ -291,7 +291,7 @@ true WIN32;NDEBUG;%(PreprocessorDefinitions) 4244;%(DisableSpecificWarnings) - MultiThreaded + MultiThreadedDLL false /arch:AVX %(AdditionalOptions) diff --git a/libs/win32/libsodium/libsodium.2015.vcxproj b/libs/win32/libsodium/libsodium.2015.vcxproj index 657ef56d32..9dbbfc3db0 100644 --- a/libs/win32/libsodium/libsodium.2015.vcxproj +++ b/libs/win32/libsodium/libsodium.2015.vcxproj @@ -210,7 +210,7 @@ Disabled SODIUM_STATIC;SODIUM_EXPORT=;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 4244;%(DisableSpecificWarnings) - MultiThreadedDebug + MultiThreadedDebugDLL /arch:AVX %(AdditionalOptions) false @@ -292,7 +292,7 @@ true SODIUM_STATIC;SODIUM_EXPORT=;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 4244;%(DisableSpecificWarnings) - MultiThreaded + MultiThreadedDLL false /arch:AVX %(AdditionalOptions)