From 0641d60e723a5064cab1144c57d8cb5634ee3ce9 Mon Sep 17 00:00:00 2001 From: Lyon Date: Sun, 7 Jul 2024 00:14:42 +0800 Subject: [PATCH] add jrpc cmd and test --- package/jrpc/jrpc.c | 94 +++++++++++++++++++ package/jrpc/jrpc.h | 5 +- port/linux/.vscode/launch.json | 3 +- .../pikascript/pikascript-lib/jrpc/jrpc.c | 94 +++++++++++++++++++ .../pikascript/pikascript-lib/jrpc/jrpc.h | 5 +- port/linux/test/module-test.cpp | 61 ++++++++++++ 6 files changed, 253 insertions(+), 9 deletions(-) diff --git a/package/jrpc/jrpc.c b/package/jrpc/jrpc.c index b33cd34f9..938ad5a98 100644 --- a/package/jrpc/jrpc.c +++ b/package/jrpc/jrpc.c @@ -677,3 +677,97 @@ int jrpc_test_server() { return ret; } + +// 将字符串按分隔符拆分的自定义实现 +char* jrpc_strtok(char* str, const char* delimiters, char** context) { + char* start = str ? str : *context; + if (!start) + return NULL; + + // 跳过分隔符 + while (*start && strchr(delimiters, *start)) + ++start; + if (!*start) + return NULL; + + char* end = start; + while (*end && !strchr(delimiters, *end)) + ++end; + + if (*end) { + *end = '\0'; + *context = end + 1; + } else { + *context = NULL; + } + + return start; +} + +char* jrpc_cmd(JRPC* jrpc, const char* cmd) { + // 使用自定义内存分配器复制命令字符串 + char* cmd_copy = jrpc_strdup(cmd); + char* context = NULL; + + // 使用自定义strtok解析命令行字符串 + char* token = jrpc_strtok(cmd_copy, " ", &context); + if (token == NULL) { + jrpc_debug("Invalid command\n"); + jrpc_free(cmd_copy); + return NULL; + } + + // 提取方法名 + char* method = jrpc_strdup(token); + + // 提取参数 + cJSON* params_array[10]; + int param_count = 0; + while ((token = jrpc_strtok(NULL, " ", &context)) != NULL) { + int param_value = atoi(token); // 假设所有参数都是整数 + params_array[param_count] = cJSON_CreateNumber(param_value); + param_count++; + } + + // 检查参数数量 + if (param_count == 0) { + jrpc_debug("No parameters provided\n"); + jrpc_free(method); + jrpc_free(cmd_copy); + return NULL; + } + + // 调用 JRPC_send_request_no_blocking + cJSON* result = + JRPC_send_request_blocking(jrpc, method, params_array, param_count); + + if (result == NULL) { + jrpc_debug("No result\n", NULL); + jrpc_free(method); + jrpc_free(cmd_copy); + return NULL; + } + + cJSON* result_data = cJSON_GetObjectItem(result, "result"); + if (NULL == result_data) { + jrpc_debug("No result Item\n", NULL); + jrpc_free(method); + jrpc_free(cmd_copy); + cJSON_Delete(result); + return NULL; + } + + char* result_str; + if (result_data) { + result_str = cJSON_Print(result_data); + // jrpc_debug("%s\n", result_str); + cJSON_Delete(result); + } + // 清理 + for (int i = 0; i < param_count; i++) { + cJSON_Delete(params_array[i]); + } + jrpc_free(method); + jrpc_free(cmd_copy); + return result_str; +} diff --git a/package/jrpc/jrpc.h b/package/jrpc/jrpc.h index c650bd890..87ebdb65f 100644 --- a/package/jrpc/jrpc.h +++ b/package/jrpc/jrpc.h @@ -108,18 +108,15 @@ cJSON* JRPC_send_request_blocking(JRPC* self, const char* method, cJSON* params[], int param_count); - cJSON* JRPC_receive_with_id_and_type(JRPC* self, int id, int type); -int jrpc_validate_response(const char* expected_response); int jrpc_compare_json_strings(const char* json_str1, const char* json_str2); int jrpc_validate_response(const char* expected_response); void set_jrpc_memory_functions(void* (*malloc_func)(size_t), void (*free_func)(void*)); - void set_jrpc_vprintf_function(int (*vprintf_func)(const char*, va_list)); - int jrpc_test_client(); int jrpc_test_server(); +char* jrpc_cmd(JRPC* jrpc, const char* cmd); #ifdef __cplusplus } diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index 607b8c6b1..4f11c40fc 100644 --- a/port/linux/.vscode/launch.json +++ b/port/linux/.vscode/launch.json @@ -30,7 +30,8 @@ // "--gtest_filter=flashdb.base" // "--gtest_filter=jrpc.server" // "--gtest_filter=jrpc.client" - "--gtest_filter=jrpc.BlockingRequestBetweenTwoJRPC" + // "--gtest_filter=jrpc.BlockingRequestBetweenTwoJRPC" + "--gtest_filter=jrpc.cmd" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/port/linux/package/pikascript/pikascript-lib/jrpc/jrpc.c b/port/linux/package/pikascript/pikascript-lib/jrpc/jrpc.c index b33cd34f9..938ad5a98 100644 --- a/port/linux/package/pikascript/pikascript-lib/jrpc/jrpc.c +++ b/port/linux/package/pikascript/pikascript-lib/jrpc/jrpc.c @@ -677,3 +677,97 @@ int jrpc_test_server() { return ret; } + +// 将字符串按分隔符拆分的自定义实现 +char* jrpc_strtok(char* str, const char* delimiters, char** context) { + char* start = str ? str : *context; + if (!start) + return NULL; + + // 跳过分隔符 + while (*start && strchr(delimiters, *start)) + ++start; + if (!*start) + return NULL; + + char* end = start; + while (*end && !strchr(delimiters, *end)) + ++end; + + if (*end) { + *end = '\0'; + *context = end + 1; + } else { + *context = NULL; + } + + return start; +} + +char* jrpc_cmd(JRPC* jrpc, const char* cmd) { + // 使用自定义内存分配器复制命令字符串 + char* cmd_copy = jrpc_strdup(cmd); + char* context = NULL; + + // 使用自定义strtok解析命令行字符串 + char* token = jrpc_strtok(cmd_copy, " ", &context); + if (token == NULL) { + jrpc_debug("Invalid command\n"); + jrpc_free(cmd_copy); + return NULL; + } + + // 提取方法名 + char* method = jrpc_strdup(token); + + // 提取参数 + cJSON* params_array[10]; + int param_count = 0; + while ((token = jrpc_strtok(NULL, " ", &context)) != NULL) { + int param_value = atoi(token); // 假设所有参数都是整数 + params_array[param_count] = cJSON_CreateNumber(param_value); + param_count++; + } + + // 检查参数数量 + if (param_count == 0) { + jrpc_debug("No parameters provided\n"); + jrpc_free(method); + jrpc_free(cmd_copy); + return NULL; + } + + // 调用 JRPC_send_request_no_blocking + cJSON* result = + JRPC_send_request_blocking(jrpc, method, params_array, param_count); + + if (result == NULL) { + jrpc_debug("No result\n", NULL); + jrpc_free(method); + jrpc_free(cmd_copy); + return NULL; + } + + cJSON* result_data = cJSON_GetObjectItem(result, "result"); + if (NULL == result_data) { + jrpc_debug("No result Item\n", NULL); + jrpc_free(method); + jrpc_free(cmd_copy); + cJSON_Delete(result); + return NULL; + } + + char* result_str; + if (result_data) { + result_str = cJSON_Print(result_data); + // jrpc_debug("%s\n", result_str); + cJSON_Delete(result); + } + // 清理 + for (int i = 0; i < param_count; i++) { + cJSON_Delete(params_array[i]); + } + jrpc_free(method); + jrpc_free(cmd_copy); + return result_str; +} diff --git a/port/linux/package/pikascript/pikascript-lib/jrpc/jrpc.h b/port/linux/package/pikascript/pikascript-lib/jrpc/jrpc.h index c650bd890..87ebdb65f 100644 --- a/port/linux/package/pikascript/pikascript-lib/jrpc/jrpc.h +++ b/port/linux/package/pikascript/pikascript-lib/jrpc/jrpc.h @@ -108,18 +108,15 @@ cJSON* JRPC_send_request_blocking(JRPC* self, const char* method, cJSON* params[], int param_count); - cJSON* JRPC_receive_with_id_and_type(JRPC* self, int id, int type); -int jrpc_validate_response(const char* expected_response); int jrpc_compare_json_strings(const char* json_str1, const char* json_str2); int jrpc_validate_response(const char* expected_response); void set_jrpc_memory_functions(void* (*malloc_func)(size_t), void (*free_func)(void*)); - void set_jrpc_vprintf_function(int (*vprintf_func)(const char*, va_list)); - int jrpc_test_client(); int jrpc_test_server(); +char* jrpc_cmd(JRPC* jrpc, const char* cmd); #ifdef __cplusplus } diff --git a/port/linux/test/module-test.cpp b/port/linux/test/module-test.cpp index 83cf5a28b..dbf1bd16e 100644 --- a/port/linux/test/module-test.cpp +++ b/port/linux/test/module-test.cpp @@ -1182,4 +1182,65 @@ TEST(jrpc, BlockingRequestBetweenTwoJRPC) { } } +// 结果回调函数示例 +void result_callback(cJSON* result) { + if (result) { + char* result_str = cJSON_Print(result); + printf("Result: %s\n", result_str); + free(result_str); + cJSON_Delete(result); + } else { + printf("No result\n"); + } +} + +char* mock_receive_cmd(void) { + static int count = 0; + count++; + switch (count) { + case 1: + return "{\"jsonrpc\": \"1.0\", \"status\": \"received\", \"id\": " + "1, " + "\"type\": 1}"; + case 2: + return "{\"jsonrpc\": \"1.0\", \"result\": 8, \"id\": 1, \"type\": " + "2}"; + default: + return NULL; + } +} + +// 测试用例:测试 jrpc_cmd 函数 +TEST(jrpc, cmd) { + JRPC jrpc = {gtest_rpc_map, + gtest_nonblocking_rpc_map, + mock_send, + mock_receive_cmd, + 0, + mock_yield, + mock_tick_ms, + 0, + {NULL}, + 0}; + + // 清空 mock_sent_message + if (mock_sent_message) { + free(mock_sent_message); + mock_sent_message = NULL; + } + + // 模拟命令行输入 "add 5 3" + char* result = jrpc_cmd(&jrpc, "add 5 3"); + + // 预期的请求字符串 + EXPECT_STREQ(result, "8"); + free(result); + + // 清理 + if (mock_sent_message) { + free(mock_sent_message); + mock_sent_message = NULL; + } +} + TEST_END