From d99e02dc8ae052b044ac255b1ec9ac76655a73c7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sun, 26 Jun 2022 15:12:33 +0930 Subject: [PATCH] strmap: add strmap_getn for non-terminated string search. Signed-off-by: Rusty Russell --- ccan/strmap/strmap.c | 17 +++++++++++------ ccan/strmap/strmap.h | 19 ++++++++++++++++++- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/ccan/strmap/strmap.c b/ccan/strmap/strmap.c index 9fa51d0d..16a30e03 100644 --- a/ccan/strmap/strmap.c +++ b/ccan/strmap/strmap.c @@ -17,9 +17,8 @@ struct node { }; /* Closest member to this in a non-empty map. */ -static struct strmap *closest(struct strmap *n, const char *member) +static struct strmap *closest(struct strmap *n, const char *member, size_t len) { - size_t len = strlen(member); const u8 *bytes = (const u8 *)member; /* Anything with NULL value is a node. */ @@ -35,20 +34,26 @@ static struct strmap *closest(struct strmap *n, const char *member) return n; } -void *strmap_get_(const struct strmap *map, const char *member) +void *strmap_getn_(const struct strmap *map, + const char *member, size_t memberlen) { struct strmap *n; /* Not empty map? */ if (map->u.n) { - n = closest((struct strmap *)map, member); - if (streq(member, n->u.s)) + n = closest((struct strmap *)map, member, memberlen); + if (!strncmp(member, n->u.s, memberlen) && !n->u.s[memberlen]) return n->v; } errno = ENOENT; return NULL; } +void *strmap_get_(const struct strmap *map, const char *member) +{ + return strmap_getn_(map, member, strlen(member)); +} + bool strmap_add_(struct strmap *map, const char *member, const void *value) { size_t len = strlen(member); @@ -68,7 +73,7 @@ bool strmap_add_(struct strmap *map, const char *member, const void *value) } /* Find closest existing member. */ - n = closest(map, member); + n = closest(map, member, len); /* Find where they differ. */ for (byte_num = 0; n->u.s[byte_num] == member[byte_num]; byte_num++) { diff --git a/ccan/strmap/strmap.h b/ccan/strmap/strmap.h index 0b32e6be..8724c31d 100644 --- a/ccan/strmap/strmap.h +++ b/ccan/strmap/strmap.h @@ -72,7 +72,7 @@ static inline bool strmap_empty_(const struct strmap *map) /** * strmap_get - get a value from a string map * @map: the typed strmap to search. - * @member: the string to search for. + * @member: the string to search for (nul terminated) * * Returns the value, or NULL if it isn't in the map (and sets errno = ENOENT). * @@ -85,6 +85,23 @@ static inline bool strmap_empty_(const struct strmap *map) tcon_cast((map), canary, strmap_get_(tcon_unwrap(map), (member))) void *strmap_get_(const struct strmap *map, const char *member); +/** + * strmap_getn - get a value from a string map + * @map: the typed strmap to search. + * @member: the string to search for. + * @memberlen: the length of @member. + * + * Returns the value, or NULL if it isn't in the map (and sets errno = ENOENT). + * + * Example: + * val = strmap_getn(&map, "hello", 5); + * if (val) + * printf("hello => %i\n", *val); + */ +#define strmap_getn(map, member, n) \ + tcon_cast((map), canary, strmap_getn_(tcon_unwrap(map), (member), (n))) +void *strmap_getn_(const struct strmap *map, const char *member, size_t n); + /** * strmap_add - place a member in the string map. * @map: the typed strmap to add to. -- 2.39.2