mirror of
https://dev.iopsys.eu/bbf/bbfdm.git
synced 2026-01-28 01:47:18 +01:00
bbfdm-api: Enhance replace_str API to utilize provided buffer
This commit is contained in:
parent
a49aa1f829
commit
b1be97457c
6 changed files with 108 additions and 67 deletions
|
|
@ -88,14 +88,15 @@ int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list,
|
|||
save_loaded_json_files(json_plugin, json_obj);
|
||||
|
||||
json_object_object_foreach(json_obj, key, jobj) {
|
||||
char node_obj[1024] = {0};
|
||||
|
||||
if (strcmp(key, "json_plugin_version") == 0) {
|
||||
json_plugin_version = json_object_get_int(jobj);
|
||||
continue;
|
||||
}
|
||||
|
||||
char *node_obj = replace_str(key, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX);
|
||||
if (node_obj == NULL) {
|
||||
replace_str(key, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX, node_obj, sizeof(node_obj));
|
||||
if (strlen(node_obj) == 0) {
|
||||
ERR("ERROR: Can't get the node object\n");
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -133,7 +134,6 @@ int load_json_plugin(struct list_head *json_plugin, struct list_head *json_list,
|
|||
dm_entryobj[0].bbfdm_type = BBFDM_BOTH;
|
||||
|
||||
parse_obj(node_obj, jobj, dm_entryobj[0].nextobj, 0, json_plugin_version, json_list);
|
||||
FREE(node_obj);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2062,44 +2062,93 @@ char *replace_char(char *str, char find, char replace)
|
|||
return str;
|
||||
}
|
||||
|
||||
char *replace_str(const char *str, const char *substr, const char *replacement)
|
||||
/**
|
||||
* Replace all occurrences of a substring in a given string with another substring.
|
||||
*
|
||||
* @param input_str The input string where replacements will be performed.
|
||||
* @param old_substr The substring to be replaced.
|
||||
* @param new_substr The substring to replace `old_substr`.
|
||||
* @param result_str The buffer to store the result. If NULL, memory will be allocated.
|
||||
* @param buffer_len The length of the buffer. If `result_str` is not NULL, this should be the size of the buffer.
|
||||
* @return A pointer to the result string. If `result_str` is provided, it will point to `result_str`, otherwise, it will be dynamically allocated.
|
||||
*/
|
||||
char *replace_str(const char *input_str, const char *old_substr, const char *new_substr, char *result_str, size_t buffer_len)
|
||||
{
|
||||
if (!str || !substr || !replacement)
|
||||
if (result_str && buffer_len > 0)
|
||||
result_str[0] = 0;
|
||||
|
||||
if (!input_str || !old_substr || !new_substr || (result_str && buffer_len == 0))
|
||||
return NULL;
|
||||
|
||||
int str_len = strlen(str);
|
||||
int substr_len = strlen(substr);
|
||||
int replacement_len = strlen(replacement);
|
||||
int cnt = 0;
|
||||
size_t input_str_len = strlen(input_str);
|
||||
size_t old_substr_len = strlen(old_substr);
|
||||
size_t new_substr_len = strlen(new_substr);
|
||||
size_t occurrences = 0;
|
||||
|
||||
if (str_len == 0)
|
||||
return strdup("");
|
||||
|
||||
if (substr_len == 0)
|
||||
return strdup(str);
|
||||
|
||||
for (int i = 0; str[i] != '\0'; i++) {
|
||||
if (DM_STRSTR(&str[i], substr) == &str[i]) {
|
||||
cnt++;
|
||||
i += substr_len - 1;
|
||||
if (input_str_len == 0) {
|
||||
// Handle case where the input string is empty
|
||||
if (result_str && buffer_len > 0) {
|
||||
return result_str;
|
||||
} else {
|
||||
return strdup("");
|
||||
}
|
||||
}
|
||||
|
||||
size_t new_str_len = str_len + cnt * (replacement_len - substr_len) + 1;
|
||||
char *value = (char *)malloc(new_str_len * sizeof(char));
|
||||
|
||||
int i = 0;
|
||||
while (*str) {
|
||||
if (strstr(str, substr) == str) {
|
||||
i += snprintf(&value[i], new_str_len - i, "%s", replacement);
|
||||
str += substr_len;
|
||||
if (old_substr_len == 0) {
|
||||
// Handle case where the input substring is empty
|
||||
if (result_str && buffer_len > 0) {
|
||||
snprintf(result_str, buffer_len, "%s", input_str);
|
||||
return result_str;
|
||||
} else {
|
||||
return strdup(input_str);
|
||||
}
|
||||
else
|
||||
value[i++] = *str++;
|
||||
}
|
||||
value[i] = '\0';
|
||||
|
||||
return value;
|
||||
// Count occurrences of old_substr in input_str
|
||||
for (size_t i = 0; input_str[i] != '\0'; i++) {
|
||||
if (strstr(&input_str[i], old_substr) == &input_str[i]) {
|
||||
occurrences++;
|
||||
i += old_substr_len;
|
||||
}
|
||||
}
|
||||
|
||||
size_t new_str_len = input_str_len + occurrences * (new_substr_len - old_substr_len) + 1;
|
||||
|
||||
if (result_str && buffer_len > 0 && new_str_len > buffer_len) {
|
||||
// Buffer size is too small
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Allocate memory only if result_str is not provided
|
||||
char *result = result_str ? result_str : (char *)malloc(new_str_len * sizeof(char));
|
||||
|
||||
if (!result) {
|
||||
// Memory allocation failed
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
while (*input_str) {
|
||||
char *match = strstr(input_str, old_substr);
|
||||
if (match == input_str) {
|
||||
// Replace old_substr with new_substr
|
||||
strncpy(&result[i], new_substr, new_substr_len);
|
||||
i += new_substr_len;
|
||||
input_str += old_substr_len;
|
||||
} else if (match) {
|
||||
// Copy characters from input_str to result until the match
|
||||
size_t len = match - input_str;
|
||||
strncpy(&result[i], input_str, len);
|
||||
i += len;
|
||||
input_str += len;
|
||||
} else {
|
||||
// No more occurrences, copy the remaining characters
|
||||
result[i++] = *input_str++;
|
||||
}
|
||||
}
|
||||
result[i] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void strip_lead_trail_whitespace(char *str)
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ bool is_regular_file(const char *path);
|
|||
unsigned long file_system_size(const char *path, const enum fs_size_type_enum type);
|
||||
void remove_char(char *str, const char c);
|
||||
char *replace_char(char *str, char find, char replace);
|
||||
char *replace_str(const char *str, const char *substr, const char *replacement);
|
||||
char *replace_str(const char *input_str, const char *old_substr, const char *new_substr, char *result_str, size_t buffer_len);
|
||||
int dm_file_to_buf(const char *filename, void *buf, size_t buf_size);
|
||||
int dm_file_copy(char *src, char *dst);
|
||||
int check_browse_section(struct uci_section *s, void *data);
|
||||
|
|
|
|||
|
|
@ -320,12 +320,12 @@ DMOBJ *find_entry_obj(DMOBJ *entryobj, char *obj_path)
|
|||
DMNODE node = {.current_object = ""};
|
||||
DMOBJ *obj = NULL;
|
||||
|
||||
char *in_obj = replace_str(obj_path, ".{i}.", ".");
|
||||
if (in_obj == NULL)
|
||||
char in_obj[1024] = {0};
|
||||
replace_str(obj_path, ".{i}.", ".", in_obj, sizeof(in_obj));
|
||||
if (strlen(in_obj) == 0)
|
||||
return NULL;
|
||||
|
||||
dm_check_dynamic_obj(&node, entryobj, in_obj, &obj);
|
||||
FREE(in_obj);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,14 +114,15 @@ static void free_loaded_json_files(struct list_head *json_list)
|
|||
void json_plugin_find_prefix_obj(const char *full_obj, char *prefix_obj, size_t len)
|
||||
{
|
||||
int last_occurent = 0, occur = 0;
|
||||
char full_object[MAX_DM_LENGTH] = {0};
|
||||
|
||||
if (!full_obj || !prefix_obj || len == 0)
|
||||
return;
|
||||
|
||||
*prefix_obj = 0;
|
||||
|
||||
char *full_object = replace_str(full_obj, ".{i}.", ".");
|
||||
if (full_object == NULL)
|
||||
replace_str(full_obj, ".{i}.", ".", full_object, sizeof(full_object));
|
||||
if (strlen(full_object) == 0)
|
||||
return;
|
||||
|
||||
unsigned int full_object_dot_num = count_occurrences(full_object, '.');
|
||||
|
|
@ -138,20 +139,20 @@ void json_plugin_find_prefix_obj(const char *full_obj, char *prefix_obj, size_t
|
|||
|
||||
*(full_object + last_occurent + 1) = 0;
|
||||
snprintf(prefix_obj, len, "%s", full_object);
|
||||
FREE(full_object);
|
||||
}
|
||||
|
||||
static void json_plugin_find_current_obj(const char *full_obj, char *curr_obj, size_t len)
|
||||
{
|
||||
int last_occurent = 0, occur = 0;
|
||||
char full_object[MAX_DM_LENGTH] = {0};
|
||||
|
||||
if (!full_obj || !curr_obj || len == 0)
|
||||
return;
|
||||
|
||||
*curr_obj = 0;
|
||||
|
||||
char *full_object = replace_str(full_obj, ".{i}.", ".");
|
||||
if (full_object == NULL)
|
||||
replace_str(full_obj, ".{i}.", ".", full_object, sizeof(full_object));
|
||||
if (strlen(full_object) == 0)
|
||||
return;
|
||||
|
||||
unsigned int full_object_dot_num = count_occurrences(full_object, '.');
|
||||
|
|
@ -168,7 +169,6 @@ static void json_plugin_find_current_obj(const char *full_obj, char *curr_obj, s
|
|||
|
||||
full_object[occur] = 0;
|
||||
snprintf(curr_obj, len, "%s", full_object + last_occurent + 1);
|
||||
FREE(full_object);
|
||||
}
|
||||
|
||||
static void generate_path_without_instance(char *full_obj, bool is_obj, char *obj_path, size_t len)
|
||||
|
|
@ -688,7 +688,7 @@ static char *uci_get_value(json_object *mapping_obj, int json_version, char *ref
|
|||
|
||||
if (linker_jobj) {
|
||||
char *link = json_object_get_string(linker_jobj);
|
||||
linker = replace_str(link, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX);
|
||||
linker = replace_str(link, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX, NULL, 0);
|
||||
}
|
||||
|
||||
if (file && type && opt_temp && strstr(refparam, "NumberOfEntries")) {
|
||||
|
|
@ -1600,7 +1600,8 @@ static void parse_param(char *object, char *param, json_object *jobj, DMLEAF *pl
|
|||
{
|
||||
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type(6)*/
|
||||
struct json_object *type = NULL, *protocols = NULL, *write = NULL, *async = NULL, *flags = NULL;
|
||||
char full_param[512] = {0};
|
||||
char full_param[1024] = {0};
|
||||
char param_ext[256] = {0};
|
||||
size_t n_flags;
|
||||
// cppcheck-suppress nullPointerRedundantCheck
|
||||
char **in_p = NULL, **out_p = NULL, **ev_arg = NULL, **tmp = NULL;
|
||||
|
|
@ -1608,8 +1609,8 @@ static void parse_param(char *object, char *param, json_object *jobj, DMLEAF *pl
|
|||
if (!jobj || !pleaf)
|
||||
return;
|
||||
|
||||
char *param_ext = replace_str(param, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX);
|
||||
if (!param_ext)
|
||||
replace_str(param, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX, param_ext, sizeof(param_ext));
|
||||
if (strlen(param_ext) == 0)
|
||||
return;
|
||||
|
||||
//PARAM
|
||||
|
|
@ -1739,7 +1740,6 @@ static void parse_param(char *object, char *param, json_object *jobj, DMLEAF *pl
|
|||
}
|
||||
|
||||
snprintf(full_param, sizeof(full_param), "%s%s", object, param_ext);
|
||||
FREE(param_ext);
|
||||
save_json_data(list, full_param, jobj, json_version, (const char**)in_p, (const char**)out_p, (const char**)ev_arg);
|
||||
}
|
||||
|
||||
|
|
@ -1768,22 +1768,21 @@ void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, int json
|
|||
DMOBJ *next_obj = NULL;
|
||||
DMLEAF *next_leaf = NULL;
|
||||
char **keys_p = NULL;
|
||||
char curr_obj[128] = {0};
|
||||
|
||||
count_obj_param_under_jsonobj(jobj, &obj_number, ¶m_number);
|
||||
|
||||
char *obj_path = replace_str(object, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX);
|
||||
if (!obj_path)
|
||||
char obj_path[MAX_DM_LENGTH] = {0};
|
||||
replace_str(object, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX, obj_path, sizeof(obj_path));
|
||||
if (strlen(obj_path) == 0)
|
||||
return;
|
||||
|
||||
char *full_obj = replace_str(obj_path, ".{i}.", ".");
|
||||
if (!full_obj) {
|
||||
FREE(obj_path);
|
||||
char full_obj[MAX_DM_LENGTH] = {0};
|
||||
replace_str(obj_path, ".{i}.", ".", full_obj, sizeof(full_obj));
|
||||
if (strlen(full_obj) == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
json_plugin_find_current_obj(full_obj, curr_obj, sizeof(curr_obj));
|
||||
FREE(obj_path);
|
||||
char curr_obj[256] = {0};
|
||||
json_plugin_find_current_obj(full_obj, curr_obj, sizeof(curr_obj));;
|
||||
|
||||
if (!pobj || strlen(curr_obj) == 0)
|
||||
return;
|
||||
|
|
@ -1862,8 +1861,6 @@ void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, int json
|
|||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
FREE(full_obj);
|
||||
}
|
||||
|
||||
int load_json_plugins(DMOBJ *entryobj, const char *plugin_path)
|
||||
|
|
@ -1877,21 +1874,21 @@ int load_json_plugins(DMOBJ *entryobj, const char *plugin_path)
|
|||
}
|
||||
|
||||
json_object_object_foreach(json, key, jobj) {
|
||||
char obj_path[MAX_DM_LENGTH] = {0};
|
||||
|
||||
if (strcmp(key, "json_plugin_version") == 0) {
|
||||
json_plugin_version = json_object_get_int(jobj);
|
||||
continue;
|
||||
}
|
||||
|
||||
char *obj_path = replace_str(key, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX);
|
||||
if (obj_path == NULL) {
|
||||
replace_str(key, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX, obj_path, sizeof(obj_path));
|
||||
if (strlen(obj_path) == 0) {
|
||||
BBF_DEBUG("ERROR: Can't get the node object");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp(obj_path, "Device.", strlen("Device.")) != 0 || obj_path[strlen(obj_path) - 1] != '.') {
|
||||
BBF_DEBUG("ERROR: Object (%s) not valid", obj_path);
|
||||
FREE(obj_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1899,7 +1896,6 @@ int load_json_plugins(DMOBJ *entryobj, const char *plugin_path)
|
|||
json_plugin_find_prefix_obj(obj_path, obj_prefix, MAX_DM_LENGTH);
|
||||
if (strlen(obj_prefix) == 0) {
|
||||
BBF_DEBUG("ERROR: Obj prefix is empty for (%s) Object", obj_path);
|
||||
FREE(obj_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1907,14 +1903,12 @@ int load_json_plugins(DMOBJ *entryobj, const char *plugin_path)
|
|||
json_plugin_find_current_obj(obj_path, curr_obj, sizeof(curr_obj));
|
||||
if (strlen(curr_obj) == 0) {
|
||||
BBF_DEBUG("ERROR: Can't get the current object from (%s) parent object", obj_path);
|
||||
FREE(obj_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
DMOBJ *dm_entryobj = find_entry_obj(entryobj, obj_prefix);
|
||||
if (!dm_entryobj) {
|
||||
BBF_DEBUG("ERROR: entry obj doesn't exist for (%s) Object", obj_prefix);
|
||||
FREE(obj_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1940,8 +1934,6 @@ int load_json_plugins(DMOBJ *entryobj, const char *plugin_path)
|
|||
memset(dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0] + (idx + 1), 0, sizeof(struct dm_obj_s));
|
||||
parse_obj(obj_path, jobj, dm_entryobj->nextdynamicobj[INDX_JSON_MOUNT].nextobj[0], idx, json_plugin_version, &json_list);
|
||||
}
|
||||
|
||||
FREE(obj_path);
|
||||
}
|
||||
|
||||
save_loaded_json_files(&loaded_json_files, json);
|
||||
|
|
|
|||
|
|
@ -964,13 +964,13 @@ static void test_bbf_api_common(void **state)
|
|||
|
||||
// replace_str: test
|
||||
DM_STRNCPY(buf, "Device.IEEE1905.AL.NetworkTopology.IEEE1905Device.{i}.IPv4Address.{i}.", sizeof(buf));
|
||||
value = replace_str(buf, ".{i}.", ".");
|
||||
value = replace_str(buf, ".{i}.", ".", NULL, 0);
|
||||
assert_string_equal(value, "Device.IEEE1905.AL.NetworkTopology.IEEE1905Device.IPv4Address.");
|
||||
FREE(value);
|
||||
|
||||
// replace_str: test
|
||||
DM_STRNCPY(buf, "Device.IEEE1905.AL.NetworkTopology.IEEE1905Device.{i}.IPv4Address.{i}.", sizeof(buf));
|
||||
value = replace_str(buf, ".{i}.", ".*.");
|
||||
value = replace_str(buf, ".{i}.", ".*.", NULL, 0);
|
||||
assert_string_equal(value, "Device.IEEE1905.AL.NetworkTopology.IEEE1905Device.*.IPv4Address.*.");
|
||||
FREE(value);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue