mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-29 17:22:56 +08:00
jrpc_cmd support parse float and string
This commit is contained in:
parent
1c925f4ce5
commit
60500ff427
@ -261,7 +261,8 @@ void JRPC_server_handle_string(JRPC* self, char* json_str) {
|
||||
jrpc_free(ack_str);
|
||||
}
|
||||
|
||||
cJSON** param_array = (cJSON**)jrpc_malloc(param_count * sizeof(cJSON*));
|
||||
cJSON** param_array =
|
||||
(cJSON**)jrpc_malloc(param_count * sizeof(cJSON*) + 1);
|
||||
if (param_array == NULL) {
|
||||
jrpc_debug("Memory allocation failed for param_array\n");
|
||||
JRPC_send_acknowledgement(self, id->valueint, ACK_MEMORY_ERROR,
|
||||
@ -726,17 +727,23 @@ int jrpc_test_server() {
|
||||
|
||||
char* jrpc_strtok(char* str, const char* delimiters, char** context) {
|
||||
char* start = str ? str : *context;
|
||||
if (!start)
|
||||
if (!start) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (*start && strchr(delimiters, *start))
|
||||
// Skip initial delimiters
|
||||
while (*start && strchr(delimiters, *start)) {
|
||||
++start;
|
||||
if (!*start)
|
||||
}
|
||||
if (!*start) {
|
||||
*context = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* end = start;
|
||||
while (*end && !strchr(delimiters, *end))
|
||||
while (*end && !strchr(delimiters, *end)) {
|
||||
++end;
|
||||
}
|
||||
|
||||
if (*end) {
|
||||
*end = '\0';
|
||||
@ -748,6 +755,36 @@ char* jrpc_strtok(char* str, const char* delimiters, char** context) {
|
||||
return start;
|
||||
}
|
||||
|
||||
static char* extract_quoted_string(const char** input) {
|
||||
const char* start = *input;
|
||||
if (*start != '"') {
|
||||
return NULL;
|
||||
}
|
||||
start++;
|
||||
const char* end = strchr(start, '"');
|
||||
if (!end) {
|
||||
return NULL;
|
||||
}
|
||||
size_t len = end - start;
|
||||
char* result = (char*)malloc(len + 1);
|
||||
if (!result) {
|
||||
return NULL;
|
||||
}
|
||||
strncpy(result, start, len);
|
||||
result[len] = '\0';
|
||||
*input = end + 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void skip_whitespace(const char** input) {
|
||||
if (input == NULL || *input == NULL) {
|
||||
return;
|
||||
}
|
||||
while (**input == ' ' || **input == '\t' || **input == '\n') {
|
||||
(*input)++;
|
||||
}
|
||||
}
|
||||
|
||||
char* JRPC_cmd(JRPC* jrpc, const char* cmd) {
|
||||
char* cmd_copy = NULL;
|
||||
char* method = NULL;
|
||||
@ -762,8 +799,10 @@ char* JRPC_cmd(JRPC* jrpc, const char* cmd) {
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
char* context = NULL;
|
||||
char* token = jrpc_strtok(cmd_copy, " ", &context);
|
||||
const char* cursor = cmd_copy;
|
||||
skip_whitespace(&cursor);
|
||||
|
||||
char* token = jrpc_strtok(cmd_copy, " ", (char**)&cursor);
|
||||
if (token == NULL) {
|
||||
jrpc_debug("Invalid command\n");
|
||||
goto __exit;
|
||||
@ -775,18 +814,52 @@ char* JRPC_cmd(JRPC* jrpc, const char* cmd) {
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
while ((token = jrpc_strtok(NULL, " ", &context)) != NULL) {
|
||||
int param_value = atoi(token);
|
||||
params_array[param_count] = cJSON_CreateNumber(param_value);
|
||||
if (!params_array[param_count]) {
|
||||
jrpc_debug("Failed to create JSON number\n");
|
||||
skip_whitespace(&cursor);
|
||||
|
||||
while (cursor && *cursor != '\0') {
|
||||
cJSON* param = NULL;
|
||||
if (*cursor == '"') {
|
||||
char* str_param = extract_quoted_string(&cursor);
|
||||
if (!str_param) {
|
||||
jrpc_debug("Failed to extract quoted string\n");
|
||||
goto __exit;
|
||||
}
|
||||
param = cJSON_CreateString(str_param);
|
||||
free(str_param);
|
||||
} else {
|
||||
const char* start = cursor;
|
||||
while (*cursor != ' ' && *cursor != '\0') {
|
||||
cursor++;
|
||||
}
|
||||
size_t len = cursor - start;
|
||||
char* token_param = (char*)malloc(len + 1);
|
||||
if (!token_param) {
|
||||
jrpc_debug("Failed to allocate memory for token_param\n");
|
||||
goto __exit;
|
||||
}
|
||||
strncpy(token_param, start, len);
|
||||
token_param[len] = '\0';
|
||||
|
||||
param = cJSON_Parse(token_param);
|
||||
if (!param) {
|
||||
param = cJSON_CreateString(token_param);
|
||||
}
|
||||
free(token_param);
|
||||
}
|
||||
if (!param) {
|
||||
jrpc_debug("Failed to create JSON parameter\n");
|
||||
goto __exit;
|
||||
}
|
||||
params_array[param_count] = param;
|
||||
param_count++;
|
||||
|
||||
skip_whitespace(&cursor);
|
||||
}
|
||||
|
||||
result =
|
||||
JRPC_send_request_blocking(jrpc, method, params_array, param_count);
|
||||
// Ensure params_array and param_count are handled correctly when
|
||||
// param_count is 0
|
||||
result = JRPC_send_request_blocking(
|
||||
jrpc, method, param_count > 0 ? params_array : NULL, param_count);
|
||||
if (result == NULL) {
|
||||
jrpc_debug("No result\n");
|
||||
goto __exit;
|
||||
|
@ -27,7 +27,7 @@ extern "C" {
|
||||
#define PARAM_COUNT_NO_CHECK -1
|
||||
|
||||
// Timeout definitions
|
||||
#define ACK_TIMEOUT 50
|
||||
#define ACK_TIMEOUT 200
|
||||
#define BLOCKING_TIMEOUT 1000
|
||||
#define RETRY_COUNT 5
|
||||
|
||||
|
3
port/linux/.vscode/launch.json
vendored
3
port/linux/.vscode/launch.json
vendored
@ -28,10 +28,11 @@
|
||||
// "--gtest_filter=time*"
|
||||
// "--gtest_filter=flashdb.tsdb1"
|
||||
// "--gtest_filter=flashdb.base"
|
||||
"--gtest_filter=jrpc.server"
|
||||
// "--gtest_filter=jrpc.server"
|
||||
// "--gtest_filter=jrpc.client"
|
||||
// "--gtest_filter=jrpc.BlockingRequestBetweenTwoJRPC"
|
||||
// "--gtest_filter=jrpc.cmd"
|
||||
"--gtest_filter=jrpc.exec_get_val"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
|
@ -261,7 +261,8 @@ void JRPC_server_handle_string(JRPC* self, char* json_str) {
|
||||
jrpc_free(ack_str);
|
||||
}
|
||||
|
||||
cJSON** param_array = (cJSON**)jrpc_malloc(param_count * sizeof(cJSON*));
|
||||
cJSON** param_array =
|
||||
(cJSON**)jrpc_malloc(param_count * sizeof(cJSON*) + 1);
|
||||
if (param_array == NULL) {
|
||||
jrpc_debug("Memory allocation failed for param_array\n");
|
||||
JRPC_send_acknowledgement(self, id->valueint, ACK_MEMORY_ERROR,
|
||||
@ -726,17 +727,23 @@ int jrpc_test_server() {
|
||||
|
||||
char* jrpc_strtok(char* str, const char* delimiters, char** context) {
|
||||
char* start = str ? str : *context;
|
||||
if (!start)
|
||||
if (!start) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (*start && strchr(delimiters, *start))
|
||||
// Skip initial delimiters
|
||||
while (*start && strchr(delimiters, *start)) {
|
||||
++start;
|
||||
if (!*start)
|
||||
}
|
||||
if (!*start) {
|
||||
*context = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* end = start;
|
||||
while (*end && !strchr(delimiters, *end))
|
||||
while (*end && !strchr(delimiters, *end)) {
|
||||
++end;
|
||||
}
|
||||
|
||||
if (*end) {
|
||||
*end = '\0';
|
||||
@ -748,6 +755,36 @@ char* jrpc_strtok(char* str, const char* delimiters, char** context) {
|
||||
return start;
|
||||
}
|
||||
|
||||
static char* extract_quoted_string(const char** input) {
|
||||
const char* start = *input;
|
||||
if (*start != '"') {
|
||||
return NULL;
|
||||
}
|
||||
start++;
|
||||
const char* end = strchr(start, '"');
|
||||
if (!end) {
|
||||
return NULL;
|
||||
}
|
||||
size_t len = end - start;
|
||||
char* result = (char*)malloc(len + 1);
|
||||
if (!result) {
|
||||
return NULL;
|
||||
}
|
||||
strncpy(result, start, len);
|
||||
result[len] = '\0';
|
||||
*input = end + 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void skip_whitespace(const char** input) {
|
||||
if (input == NULL || *input == NULL) {
|
||||
return;
|
||||
}
|
||||
while (**input == ' ' || **input == '\t' || **input == '\n') {
|
||||
(*input)++;
|
||||
}
|
||||
}
|
||||
|
||||
char* JRPC_cmd(JRPC* jrpc, const char* cmd) {
|
||||
char* cmd_copy = NULL;
|
||||
char* method = NULL;
|
||||
@ -762,8 +799,10 @@ char* JRPC_cmd(JRPC* jrpc, const char* cmd) {
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
char* context = NULL;
|
||||
char* token = jrpc_strtok(cmd_copy, " ", &context);
|
||||
const char* cursor = cmd_copy;
|
||||
skip_whitespace(&cursor);
|
||||
|
||||
char* token = jrpc_strtok(cmd_copy, " ", (char**)&cursor);
|
||||
if (token == NULL) {
|
||||
jrpc_debug("Invalid command\n");
|
||||
goto __exit;
|
||||
@ -775,18 +814,52 @@ char* JRPC_cmd(JRPC* jrpc, const char* cmd) {
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
while ((token = jrpc_strtok(NULL, " ", &context)) != NULL) {
|
||||
int param_value = atoi(token);
|
||||
params_array[param_count] = cJSON_CreateNumber(param_value);
|
||||
if (!params_array[param_count]) {
|
||||
jrpc_debug("Failed to create JSON number\n");
|
||||
skip_whitespace(&cursor);
|
||||
|
||||
while (cursor && *cursor != '\0') {
|
||||
cJSON* param = NULL;
|
||||
if (*cursor == '"') {
|
||||
char* str_param = extract_quoted_string(&cursor);
|
||||
if (!str_param) {
|
||||
jrpc_debug("Failed to extract quoted string\n");
|
||||
goto __exit;
|
||||
}
|
||||
param = cJSON_CreateString(str_param);
|
||||
free(str_param);
|
||||
} else {
|
||||
const char* start = cursor;
|
||||
while (*cursor != ' ' && *cursor != '\0') {
|
||||
cursor++;
|
||||
}
|
||||
size_t len = cursor - start;
|
||||
char* token_param = (char*)malloc(len + 1);
|
||||
if (!token_param) {
|
||||
jrpc_debug("Failed to allocate memory for token_param\n");
|
||||
goto __exit;
|
||||
}
|
||||
strncpy(token_param, start, len);
|
||||
token_param[len] = '\0';
|
||||
|
||||
param = cJSON_Parse(token_param);
|
||||
if (!param) {
|
||||
param = cJSON_CreateString(token_param);
|
||||
}
|
||||
free(token_param);
|
||||
}
|
||||
if (!param) {
|
||||
jrpc_debug("Failed to create JSON parameter\n");
|
||||
goto __exit;
|
||||
}
|
||||
params_array[param_count] = param;
|
||||
param_count++;
|
||||
|
||||
skip_whitespace(&cursor);
|
||||
}
|
||||
|
||||
result =
|
||||
JRPC_send_request_blocking(jrpc, method, params_array, param_count);
|
||||
// Ensure params_array and param_count are handled correctly when
|
||||
// param_count is 0
|
||||
result = JRPC_send_request_blocking(
|
||||
jrpc, method, param_count > 0 ? params_array : NULL, param_count);
|
||||
if (result == NULL) {
|
||||
jrpc_debug("No result\n");
|
||||
goto __exit;
|
||||
|
@ -27,7 +27,7 @@ extern "C" {
|
||||
#define PARAM_COUNT_NO_CHECK -1
|
||||
|
||||
// Timeout definitions
|
||||
#define ACK_TIMEOUT 50
|
||||
#define ACK_TIMEOUT 200
|
||||
#define BLOCKING_TIMEOUT 1000
|
||||
#define RETRY_COUNT 5
|
||||
|
||||
|
@ -940,19 +940,42 @@ static unsigned long mock_tick_ms(void) {
|
||||
return pika_platform_get_tick();
|
||||
}
|
||||
|
||||
rpc_mapping gtest_rpc_map[] = {{"add",
|
||||
[](cJSON* params[], int param_count) -> cJSON* {
|
||||
int a = params[0]->valueint;
|
||||
int b = params[1]->valueint;
|
||||
return cJSON_CreateNumber(a + b);
|
||||
},
|
||||
2},
|
||||
{"get_val",
|
||||
[](cJSON* params[], int param_count) -> cJSON* {
|
||||
return cJSON_CreateNumber(2478);
|
||||
},
|
||||
0},
|
||||
RPC_MAP_END};
|
||||
rpc_mapping gtest_rpc_map[] = {
|
||||
{"add",
|
||||
[](cJSON* params[], int param_count) -> cJSON* {
|
||||
int a = params[0]->valueint;
|
||||
int b = params[1]->valueint;
|
||||
return cJSON_CreateNumber(a + b);
|
||||
},
|
||||
2},
|
||||
{"get_val",
|
||||
[](cJSON* params[], int param_count) -> cJSON* {
|
||||
return cJSON_CreateNumber(2478);
|
||||
},
|
||||
0},
|
||||
{"concat",
|
||||
[](cJSON* params[], int param_count) -> cJSON* {
|
||||
const char* str1 = params[0]->valuestring;
|
||||
const char* str2 = params[1]->valuestring;
|
||||
size_t len = strlen(str1) + strlen(str2) + 1;
|
||||
char* result_str = (char*)malloc(len);
|
||||
if (!result_str)
|
||||
return NULL;
|
||||
strcpy(result_str, str1);
|
||||
strcat(result_str, str2);
|
||||
cJSON* result = cJSON_CreateString(result_str);
|
||||
free(result_str);
|
||||
return result;
|
||||
},
|
||||
2},
|
||||
{"multiply",
|
||||
[](cJSON* params[], int param_count) -> cJSON* {
|
||||
double a = params[0]->valuedouble;
|
||||
double b = params[1]->valuedouble;
|
||||
return cJSON_CreateNumber(a * b);
|
||||
},
|
||||
2},
|
||||
RPC_MAP_END};
|
||||
|
||||
rpc_mapping_nonblocking gtest_nonblocking_rpc_map[] = {RPC_MAP_END};
|
||||
|
||||
@ -1313,4 +1336,39 @@ TEST(jrpc, exec_par_num_err) {
|
||||
EXPECT_STREQ(response, NULL);
|
||||
}
|
||||
|
||||
TEST(jrpc, exec_concat) {
|
||||
char* response = execute_cmd("concat hello world");
|
||||
EXPECT_STREQ(response, "\"helloworld\"");
|
||||
free(response);
|
||||
}
|
||||
|
||||
TEST(jrpc, exec_multiply) {
|
||||
char* response = execute_cmd("multiply 3.5 2.0");
|
||||
EXPECT_STREQ(response, "7");
|
||||
free(response);
|
||||
}
|
||||
|
||||
TEST(jrpc, exec_multiply_integer) {
|
||||
char* response = execute_cmd("multiply 3 2");
|
||||
EXPECT_STREQ(response, "6");
|
||||
free(response);
|
||||
}
|
||||
|
||||
TEST(jrpc, exec_concat_num_err) {
|
||||
char* response = execute_cmd("concat hello");
|
||||
EXPECT_EQ(response, nullptr);
|
||||
}
|
||||
|
||||
TEST(jrpc, exec_concat_str) {
|
||||
char* response = execute_cmd("concat \"hello\" \"world\"");
|
||||
EXPECT_STREQ(response, "\"helloworld\"");
|
||||
free(response);
|
||||
}
|
||||
|
||||
TEST(jrpc, exec_concat_str_space) {
|
||||
char* response = execute_cmd("concat \"he llo\" \"world\"");
|
||||
EXPECT_STREQ(response, "\"he lloworld\"");
|
||||
free(response);
|
||||
}
|
||||
|
||||
TEST_END
|
||||
|
@ -2,4 +2,4 @@
|
||||
#define PIKA_VERSION_MINOR 13
|
||||
#define PIKA_VERSION_MICRO 3
|
||||
|
||||
#define PIKA_EDIT_TIME "2024/07/10 20:34:31"
|
||||
#define PIKA_EDIT_TIME "2024/07/15 17:00:25"
|
||||
|
Loading…
x
Reference in New Issue
Block a user