mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 08:46:58 +08:00
optimized str_replace_str
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
#include <str.h>
|
||||
#include <common.h>
|
||||
|
||||
|
||||
static
|
||||
int replace_cmd(struct main_server_st* s, proc_st *proc,
|
||||
char **cmd, const char* pattern,
|
||||
@@ -38,6 +39,13 @@ int replace_cmd(struct main_server_st* s, proc_st *proc,
|
||||
{
|
||||
str_st str;
|
||||
int ret;
|
||||
str_rep_tab tab[5];
|
||||
|
||||
STR_TAB_SET(0, "%{R}", route);
|
||||
STR_TAB_SET(1, "%R", route);
|
||||
STR_TAB_SET(2, "%{D}", dev);
|
||||
STR_TAB_SET(3, "%D", dev);
|
||||
STR_TAB_TERM(4);
|
||||
|
||||
str_init(&str, proc);
|
||||
|
||||
@@ -45,20 +53,7 @@ int replace_cmd(struct main_server_st* s, proc_st *proc,
|
||||
if (ret < 0)
|
||||
return ERR_MEM;
|
||||
|
||||
ret = str_replace_str(&str, "%{R}", route);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
ret = str_replace_str(&str, "%{D}", dev);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
/* The old compatibility strings */
|
||||
ret = str_replace_str(&str, "%R", route);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
ret = str_replace_str(&str, "%D", dev);
|
||||
ret = str_replace_str(&str, tab);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
|
||||
72
src/str.c
72
src/str.c
@@ -149,41 +149,61 @@ str_append_printf(str_st *dest, const char *fmt, ...)
|
||||
return len;
|
||||
}
|
||||
|
||||
int str_replace_str(str_st *str, const char *what, const char *with)
|
||||
int str_replace_str(str_st *str, const str_rep_tab *tab)
|
||||
{
|
||||
uint8_t *p, *final;
|
||||
unsigned what_len, final_len;
|
||||
int ret;
|
||||
uint8_t *p;
|
||||
const str_rep_tab *ptab;
|
||||
unsigned length;
|
||||
char *final;
|
||||
unsigned final_len;
|
||||
int ret, pos;
|
||||
|
||||
what_len = strlen(what);
|
||||
p = str->data;
|
||||
pos = 0;
|
||||
do {
|
||||
p = memchr(p, '%', str->length - pos);
|
||||
if (p == NULL)
|
||||
break;
|
||||
|
||||
p = memmem(str->data, str->length, what, what_len);
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
pos = (ptrdiff_t)(p-str->data);
|
||||
|
||||
p += what_len;
|
||||
final_len = str->length - (ptrdiff_t)(p-str->data);
|
||||
length = str->length - pos;
|
||||
|
||||
final = talloc_memdup(str->allocd, p, final_len);
|
||||
if (final == NULL)
|
||||
return -1;
|
||||
ptab = tab;
|
||||
do {
|
||||
if (length >= ptab->pattern_length &&
|
||||
memcmp(ptab->pattern, p, ptab->pattern_length) == 0) {
|
||||
/* replace */
|
||||
final_len = length - ptab->pattern_length;
|
||||
final = talloc_memdup(str->allocd, p+ptab->pattern_length, final_len);
|
||||
if (final == NULL)
|
||||
return -1;
|
||||
|
||||
str->length -= final_len + what_len;
|
||||
str->length -= final_len + ptab->pattern_length;
|
||||
ret = str_append_str(str, ptab->rep_val);
|
||||
if (ret < 0) {
|
||||
talloc_free(final);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = str_append_str(str, with);
|
||||
if (ret < 0) {
|
||||
talloc_free(final);
|
||||
return ret;
|
||||
}
|
||||
ret = str_append_data(str, final, final_len);
|
||||
talloc_free(final);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ptab++;
|
||||
|
||||
ret = str_append_data(str, final, final_len);
|
||||
talloc_free(final);
|
||||
if (ptab->pattern == NULL) {
|
||||
/* not found */
|
||||
return -1;
|
||||
}
|
||||
} while(1);
|
||||
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
p = &str->data[pos];
|
||||
} while(pos < str->length);
|
||||
|
||||
/* allow multiple replacements */
|
||||
return str_replace_str(str, what, with);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
15
src/str.h
15
src/str.h
@@ -26,6 +26,19 @@
|
||||
#include <config.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define STR_TAB_SET(i,pat,val) { \
|
||||
tab[i].pattern = pat; \
|
||||
tab[i].pattern_length = sizeof(pat)-1; \
|
||||
tab[i].rep_val = val; \
|
||||
}
|
||||
#define STR_TAB_TERM(i) tab[i].pattern = NULL
|
||||
|
||||
typedef struct {
|
||||
const char *pattern;
|
||||
unsigned pattern_length;
|
||||
const char *rep_val;
|
||||
} str_rep_tab;
|
||||
|
||||
typedef struct {
|
||||
uint8_t *allocd; /* pointer to allocated data */
|
||||
uint8_t *data; /* API: pointer to data to copy from */
|
||||
@@ -55,7 +68,7 @@ inline static void str_reset(str_st * buf)
|
||||
|
||||
int str_append_printf(str_st *dest, const char *fmt, ...);
|
||||
int str_append_str(str_st *, const char *str);
|
||||
int str_replace_str(str_st *, const char *what, const char *with);
|
||||
int str_replace_str(str_st *, const str_rep_tab *tab);
|
||||
int str_append_data(str_st *, const void *data, size_t data_size);
|
||||
int str_append_size(str_st *, size_t data_size);
|
||||
int str_append_data_prefix1(str_st *, const void *data, size_t data_size);
|
||||
|
||||
@@ -1250,6 +1250,11 @@ char *replace_vals(worker_st *ws, const char *txt)
|
||||
{
|
||||
str_st str;
|
||||
int ret;
|
||||
str_rep_tab tab[3];
|
||||
|
||||
STR_TAB_SET(0, "%{U}", ws->username);
|
||||
STR_TAB_SET(1, "%{G}", ws->groupname);
|
||||
STR_TAB_TERM(2);
|
||||
|
||||
str_init(&str, ws);
|
||||
|
||||
@@ -1257,13 +1262,7 @@ char *replace_vals(worker_st *ws, const char *txt)
|
||||
if (ret < 0)
|
||||
return NULL;
|
||||
|
||||
ret = str_replace_str(&str, "%{U}", ws->username);
|
||||
if (ret < 0) {
|
||||
str_clear(&str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = str_replace_str(&str, "%{G}", ws->groupname);
|
||||
ret = str_replace_str(&str, tab);
|
||||
if (ret < 0) {
|
||||
str_clear(&str);
|
||||
return NULL;
|
||||
|
||||
Reference in New Issue
Block a user