From 0df3dfacc4f10036f86b847f44c5e9df46129be3 Mon Sep 17 00:00:00 2001 From: Christoph Huber Date: Wed, 19 Jul 2023 09:33:53 +0200 Subject: [PATCH 1/5] fmt: search substring in pointer-length object --- include/re_fmt.h | 1 + src/fmt/pl.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/re_fmt.h b/include/re_fmt.h index 540caa624..93adaa83b 100644 --- a/include/re_fmt.h +++ b/include/re_fmt.h @@ -49,6 +49,7 @@ int pl_cmp(const struct pl *pl1, const struct pl *pl2); int pl_casecmp(const struct pl *pl1, const struct pl *pl2); const char *pl_strchr(const struct pl *pl, char c); const char *pl_strrchr(const struct pl *pl, char c); +const char *pl_strstr(const struct pl *pl, const char *str); int pl_trim(struct pl *pl); int pl_ltrim(struct pl *pl); int pl_rtrim(struct pl *pl); diff --git a/src/fmt/pl.c b/src/fmt/pl.c index e1e11a7f1..e9b568967 100644 --- a/src/fmt/pl.c +++ b/src/fmt/pl.c @@ -655,6 +655,39 @@ const char *pl_strrchr(const struct pl *pl, char c) } +/** + * Locate the fist substring in a pointer-length string + * + * @param pl Pointer-length string + * @param str Substring to locate + * + * @return Pointer to first char if substring is found, otherwise NULL + */ +const char *pl_strstr(const struct pl *pl, const char *str) +{ + unsigned int i; + + /*case pl not set & pl is not long enough*/ + if (!pl_isset(pl) || pl->l < str_len(str)) + return NULL; + + /*case str is empty or just '\0'*/ + if (!str_len(str)) + return pl->p; + + for (i = 0; i < pl->l; ++i) { + /*case rest of pl is not long enough*/ + if (pl->l - i < str_len(str)) + return NULL; + + if (!memcmp(pl->p + i, str, str_len(str))) + return pl->p + i; + } + + return NULL; +} + + /** * Trim white space characters at start of pointer-length string * From 41c008f44879f432ef57b29ef395554319e1397c Mon Sep 17 00:00:00 2001 From: Christoph Huber Date: Wed, 19 Jul 2023 09:18:59 +0200 Subject: [PATCH 2/5] fmt: pl_strstr testcases --- test/fmt.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/fmt.c b/test/fmt.c index eea4e9ba7..381f412fe 100644 --- a/test/fmt.c +++ b/test/fmt.c @@ -30,6 +30,8 @@ int test_fmt_pl(void) const struct pl pl4 = PL("rattarei4"); const char str0[] = "rattarei"; const char str1[] = "rattaray"; + const char str2[] = "foo"; + const char str3[] = "bar"; struct pl pl5, pl6; const struct pl pl7 = PL("hei"); const struct pl pl7_ = PL("Hei"); @@ -116,6 +118,20 @@ int test_fmt_pl(void) if (NULL != pl_strrchr(&pl_empty, 'r')) goto out; + /* pl_strstr() */ + if (pl.p != pl_strstr(&pl, str0)) + goto out; + if (pl1.p != pl_strstr(&pl1, str2)) + goto out; + if (pl1.p + 3 != pl_strstr(&pl1, str3)) + goto out; + if (NULL != pl_strstr(&pl, str1)) + goto out; + if (pl.p != pl_strstr(&pl, "")) + goto out; + if (NULL != pl_strstr(&pl1, str0)) + goto out; + return 0; out: return EINVAL; From 1582053b7c74c4dc3caab5a773249db365e35124 Mon Sep 17 00:00:00 2001 From: Christoph Huber Date: Wed, 19 Jul 2023 09:36:41 +0200 Subject: [PATCH 3/5] fmt: convert pointer-length hex string to binary --- include/re_fmt.h | 1 + src/fmt/pl.c | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/include/re_fmt.h b/include/re_fmt.h index 93adaa83b..5b6e35dd7 100644 --- a/include/re_fmt.h +++ b/include/re_fmt.h @@ -39,6 +39,7 @@ uint64_t pl_u64(const struct pl *pl); uint64_t pl_x64(const struct pl *pl); double pl_float(const struct pl *pl); int pl_bool(bool *val, const struct pl *pl); +int pl_hex(const struct pl *pl, uint8_t *hex, unsigned int len); bool pl_isset(const struct pl *pl); int pl_strcpy(const struct pl *pl, char *str, size_t size); int pl_strdup(char **dst, const struct pl *src); diff --git a/src/fmt/pl.c b/src/fmt/pl.c index e9b568967..c719249b7 100644 --- a/src/fmt/pl.c +++ b/src/fmt/pl.c @@ -355,6 +355,31 @@ int pl_bool(bool *val, const struct pl *pl) } +/** + * Convert an ASCII hex string as a pointer-length object to binary format + * + * @param pl Pointer-length object + * @param hex Destination binary buffer + * @param len Length of binary buffer + * + * @return 0 if success, otherwise errorcode + */ +int pl_hex(const struct pl *pl, uint8_t *hex, unsigned int len) +{ + unsigned int i; + + if (!pl_isset(pl) || !hex || (pl->l != (2 * len))) + return EINVAL; + + for (i = 0; i < pl->l; i += 2) { + hex[i/2] = ch_hex(*(pl->p + i)) << 4; + hex[i/2] += ch_hex(*(pl->p + i +1)); + } + + return 0; +} + + /** * Check if pointer-length object is set * From cd8e22bbc0bdcf1a942a3c45daf10a0d6911b1f9 Mon Sep 17 00:00:00 2001 From: Christoph Huber Date: Tue, 25 Jul 2023 12:41:25 +0200 Subject: [PATCH 4/5] fmt: buffer string length for improved runtime --- include/re_fmt.h | 2 +- src/fmt/pl.c | 18 ++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/include/re_fmt.h b/include/re_fmt.h index 5b6e35dd7..91dba08cb 100644 --- a/include/re_fmt.h +++ b/include/re_fmt.h @@ -39,7 +39,7 @@ uint64_t pl_u64(const struct pl *pl); uint64_t pl_x64(const struct pl *pl); double pl_float(const struct pl *pl); int pl_bool(bool *val, const struct pl *pl); -int pl_hex(const struct pl *pl, uint8_t *hex, unsigned int len); +int pl_hex(const struct pl *pl, uint8_t *hex, size_t len); bool pl_isset(const struct pl *pl); int pl_strcpy(const struct pl *pl, char *str, size_t size); int pl_strdup(char **dst, const struct pl *src); diff --git a/src/fmt/pl.c b/src/fmt/pl.c index c719249b7..0785a6d85 100644 --- a/src/fmt/pl.c +++ b/src/fmt/pl.c @@ -364,14 +364,12 @@ int pl_bool(bool *val, const struct pl *pl) * * @return 0 if success, otherwise errorcode */ -int pl_hex(const struct pl *pl, uint8_t *hex, unsigned int len) +int pl_hex(const struct pl *pl, uint8_t *hex, size_t len) { - unsigned int i; - if (!pl_isset(pl) || !hex || (pl->l != (2 * len))) return EINVAL; - for (i = 0; i < pl->l; i += 2) { + for (size_t i = 0; i < pl->l; i += 2) { hex[i/2] = ch_hex(*(pl->p + i)) << 4; hex[i/2] += ch_hex(*(pl->p + i +1)); } @@ -690,22 +688,22 @@ const char *pl_strrchr(const struct pl *pl, char c) */ const char *pl_strstr(const struct pl *pl, const char *str) { - unsigned int i; + size_t len = str_len(str); /*case pl not set & pl is not long enough*/ - if (!pl_isset(pl) || pl->l < str_len(str)) + if (!pl_isset(pl) || pl->l < len) return NULL; /*case str is empty or just '\0'*/ - if (!str_len(str)) + if (!len) return pl->p; - for (i = 0; i < pl->l; ++i) { + for (size_t i = 0; i < pl->l; ++i) { /*case rest of pl is not long enough*/ - if (pl->l - i < str_len(str)) + if (pl->l - i < len) return NULL; - if (!memcmp(pl->p + i, str, str_len(str))) + if (!memcmp(pl->p + i, str, len)) return pl->p + i; } From 8a9a43c142dea135627d80fc753da6a00333810e Mon Sep 17 00:00:00 2001 From: Christoph Huber Date: Tue, 25 Jul 2023 13:09:08 +0200 Subject: [PATCH 5/5] fmt: fix typo --- src/fmt/pl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fmt/pl.c b/src/fmt/pl.c index 0785a6d85..32edd193b 100644 --- a/src/fmt/pl.c +++ b/src/fmt/pl.c @@ -679,7 +679,7 @@ const char *pl_strrchr(const struct pl *pl, char c) /** - * Locate the fist substring in a pointer-length string + * Locate the first substring in a pointer-length string * * @param pl Pointer-length string * @param str Substring to locate