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);
|
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) {
|
if (param_array == NULL) {
|
||||||
jrpc_debug("Memory allocation failed for param_array\n");
|
jrpc_debug("Memory allocation failed for param_array\n");
|
||||||
JRPC_send_acknowledgement(self, id->valueint, ACK_MEMORY_ERROR,
|
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* jrpc_strtok(char* str, const char* delimiters, char** context) {
|
||||||
char* start = str ? str : *context;
|
char* start = str ? str : *context;
|
||||||
if (!start)
|
if (!start) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
while (*start && strchr(delimiters, *start))
|
// Skip initial delimiters
|
||||||
|
while (*start && strchr(delimiters, *start)) {
|
||||||
++start;
|
++start;
|
||||||
if (!*start)
|
}
|
||||||
|
if (!*start) {
|
||||||
|
*context = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
char* end = start;
|
char* end = start;
|
||||||
while (*end && !strchr(delimiters, *end))
|
while (*end && !strchr(delimiters, *end)) {
|
||||||
++end;
|
++end;
|
||||||
|
}
|
||||||
|
|
||||||
if (*end) {
|
if (*end) {
|
||||||
*end = '\0';
|
*end = '\0';
|
||||||
@ -748,6 +755,36 @@ char* jrpc_strtok(char* str, const char* delimiters, char** context) {
|
|||||||
return start;
|
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* JRPC_cmd(JRPC* jrpc, const char* cmd) {
|
||||||
char* cmd_copy = NULL;
|
char* cmd_copy = NULL;
|
||||||
char* method = NULL;
|
char* method = NULL;
|
||||||
@ -762,8 +799,10 @@ char* JRPC_cmd(JRPC* jrpc, const char* cmd) {
|
|||||||
goto __exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* context = NULL;
|
const char* cursor = cmd_copy;
|
||||||
char* token = jrpc_strtok(cmd_copy, " ", &context);
|
skip_whitespace(&cursor);
|
||||||
|
|
||||||
|
char* token = jrpc_strtok(cmd_copy, " ", (char**)&cursor);
|
||||||
if (token == NULL) {
|
if (token == NULL) {
|
||||||
jrpc_debug("Invalid command\n");
|
jrpc_debug("Invalid command\n");
|
||||||
goto __exit;
|
goto __exit;
|
||||||
@ -775,18 +814,52 @@ char* JRPC_cmd(JRPC* jrpc, const char* cmd) {
|
|||||||
goto __exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((token = jrpc_strtok(NULL, " ", &context)) != NULL) {
|
skip_whitespace(&cursor);
|
||||||
int param_value = atoi(token);
|
|
||||||
params_array[param_count] = cJSON_CreateNumber(param_value);
|
while (cursor && *cursor != '\0') {
|
||||||
if (!params_array[param_count]) {
|
cJSON* param = NULL;
|
||||||
jrpc_debug("Failed to create JSON number\n");
|
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;
|
goto __exit;
|
||||||
}
|
}
|
||||||
|
params_array[param_count] = param;
|
||||||
param_count++;
|
param_count++;
|
||||||
|
|
||||||
|
skip_whitespace(&cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
result =
|
// Ensure params_array and param_count are handled correctly when
|
||||||
JRPC_send_request_blocking(jrpc, method, params_array, param_count);
|
// param_count is 0
|
||||||
|
result = JRPC_send_request_blocking(
|
||||||
|
jrpc, method, param_count > 0 ? params_array : NULL, param_count);
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
jrpc_debug("No result\n");
|
jrpc_debug("No result\n");
|
||||||
goto __exit;
|
goto __exit;
|
||||||
|
@ -27,7 +27,7 @@ extern "C" {
|
|||||||
#define PARAM_COUNT_NO_CHECK -1
|
#define PARAM_COUNT_NO_CHECK -1
|
||||||
|
|
||||||
// Timeout definitions
|
// Timeout definitions
|
||||||
#define ACK_TIMEOUT 50
|
#define ACK_TIMEOUT 200
|
||||||
#define BLOCKING_TIMEOUT 1000
|
#define BLOCKING_TIMEOUT 1000
|
||||||
#define RETRY_COUNT 5
|
#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=time*"
|
||||||
// "--gtest_filter=flashdb.tsdb1"
|
// "--gtest_filter=flashdb.tsdb1"
|
||||||
// "--gtest_filter=flashdb.base"
|
// "--gtest_filter=flashdb.base"
|
||||||
"--gtest_filter=jrpc.server"
|
// "--gtest_filter=jrpc.server"
|
||||||
// "--gtest_filter=jrpc.client"
|
// "--gtest_filter=jrpc.client"
|
||||||
// "--gtest_filter=jrpc.BlockingRequestBetweenTwoJRPC"
|
// "--gtest_filter=jrpc.BlockingRequestBetweenTwoJRPC"
|
||||||
// "--gtest_filter=jrpc.cmd"
|
// "--gtest_filter=jrpc.cmd"
|
||||||
|
"--gtest_filter=jrpc.exec_get_val"
|
||||||
],
|
],
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
|
@ -261,7 +261,8 @@ void JRPC_server_handle_string(JRPC* self, char* json_str) {
|
|||||||
jrpc_free(ack_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) {
|
if (param_array == NULL) {
|
||||||
jrpc_debug("Memory allocation failed for param_array\n");
|
jrpc_debug("Memory allocation failed for param_array\n");
|
||||||
JRPC_send_acknowledgement(self, id->valueint, ACK_MEMORY_ERROR,
|
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* jrpc_strtok(char* str, const char* delimiters, char** context) {
|
||||||
char* start = str ? str : *context;
|
char* start = str ? str : *context;
|
||||||
if (!start)
|
if (!start) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
while (*start && strchr(delimiters, *start))
|
// Skip initial delimiters
|
||||||
|
while (*start && strchr(delimiters, *start)) {
|
||||||
++start;
|
++start;
|
||||||
if (!*start)
|
}
|
||||||
|
if (!*start) {
|
||||||
|
*context = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
char* end = start;
|
char* end = start;
|
||||||
while (*end && !strchr(delimiters, *end))
|
while (*end && !strchr(delimiters, *end)) {
|
||||||
++end;
|
++end;
|
||||||
|
}
|
||||||
|
|
||||||
if (*end) {
|
if (*end) {
|
||||||
*end = '\0';
|
*end = '\0';
|
||||||
@ -748,6 +755,36 @@ char* jrpc_strtok(char* str, const char* delimiters, char** context) {
|
|||||||
return start;
|
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* JRPC_cmd(JRPC* jrpc, const char* cmd) {
|
||||||
char* cmd_copy = NULL;
|
char* cmd_copy = NULL;
|
||||||
char* method = NULL;
|
char* method = NULL;
|
||||||
@ -762,8 +799,10 @@ char* JRPC_cmd(JRPC* jrpc, const char* cmd) {
|
|||||||
goto __exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* context = NULL;
|
const char* cursor = cmd_copy;
|
||||||
char* token = jrpc_strtok(cmd_copy, " ", &context);
|
skip_whitespace(&cursor);
|
||||||
|
|
||||||
|
char* token = jrpc_strtok(cmd_copy, " ", (char**)&cursor);
|
||||||
if (token == NULL) {
|
if (token == NULL) {
|
||||||
jrpc_debug("Invalid command\n");
|
jrpc_debug("Invalid command\n");
|
||||||
goto __exit;
|
goto __exit;
|
||||||
@ -775,18 +814,52 @@ char* JRPC_cmd(JRPC* jrpc, const char* cmd) {
|
|||||||
goto __exit;
|
goto __exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((token = jrpc_strtok(NULL, " ", &context)) != NULL) {
|
skip_whitespace(&cursor);
|
||||||
int param_value = atoi(token);
|
|
||||||
params_array[param_count] = cJSON_CreateNumber(param_value);
|
while (cursor && *cursor != '\0') {
|
||||||
if (!params_array[param_count]) {
|
cJSON* param = NULL;
|
||||||
jrpc_debug("Failed to create JSON number\n");
|
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;
|
goto __exit;
|
||||||
}
|
}
|
||||||
|
params_array[param_count] = param;
|
||||||
param_count++;
|
param_count++;
|
||||||
|
|
||||||
|
skip_whitespace(&cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
result =
|
// Ensure params_array and param_count are handled correctly when
|
||||||
JRPC_send_request_blocking(jrpc, method, params_array, param_count);
|
// param_count is 0
|
||||||
|
result = JRPC_send_request_blocking(
|
||||||
|
jrpc, method, param_count > 0 ? params_array : NULL, param_count);
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
jrpc_debug("No result\n");
|
jrpc_debug("No result\n");
|
||||||
goto __exit;
|
goto __exit;
|
||||||
|
@ -27,7 +27,7 @@ extern "C" {
|
|||||||
#define PARAM_COUNT_NO_CHECK -1
|
#define PARAM_COUNT_NO_CHECK -1
|
||||||
|
|
||||||
// Timeout definitions
|
// Timeout definitions
|
||||||
#define ACK_TIMEOUT 50
|
#define ACK_TIMEOUT 200
|
||||||
#define BLOCKING_TIMEOUT 1000
|
#define BLOCKING_TIMEOUT 1000
|
||||||
#define RETRY_COUNT 5
|
#define RETRY_COUNT 5
|
||||||
|
|
||||||
|
@ -940,19 +940,42 @@ static unsigned long mock_tick_ms(void) {
|
|||||||
return pika_platform_get_tick();
|
return pika_platform_get_tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
rpc_mapping gtest_rpc_map[] = {{"add",
|
rpc_mapping gtest_rpc_map[] = {
|
||||||
[](cJSON* params[], int param_count) -> cJSON* {
|
{"add",
|
||||||
int a = params[0]->valueint;
|
[](cJSON* params[], int param_count) -> cJSON* {
|
||||||
int b = params[1]->valueint;
|
int a = params[0]->valueint;
|
||||||
return cJSON_CreateNumber(a + b);
|
int b = params[1]->valueint;
|
||||||
},
|
return cJSON_CreateNumber(a + b);
|
||||||
2},
|
},
|
||||||
{"get_val",
|
2},
|
||||||
[](cJSON* params[], int param_count) -> cJSON* {
|
{"get_val",
|
||||||
return cJSON_CreateNumber(2478);
|
[](cJSON* params[], int param_count) -> cJSON* {
|
||||||
},
|
return cJSON_CreateNumber(2478);
|
||||||
0},
|
},
|
||||||
RPC_MAP_END};
|
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};
|
rpc_mapping_nonblocking gtest_nonblocking_rpc_map[] = {RPC_MAP_END};
|
||||||
|
|
||||||
@ -1313,4 +1336,39 @@ TEST(jrpc, exec_par_num_err) {
|
|||||||
EXPECT_STREQ(response, NULL);
|
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
|
TEST_END
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
#define PIKA_VERSION_MINOR 13
|
#define PIKA_VERSION_MINOR 13
|
||||||
#define PIKA_VERSION_MICRO 3
|
#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