1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

lws_dll2: add helper for typed object name from owner list

There's a good pattern that's encouraged by using lws_struct pieces, that
we have an lws_dll2 owner with an array of objects listed in it that exist
in an lwsac.  And because it came from JSON, there is tending to be a
logical name for the objects.

This adds a typed helper and wrapper to scan the owner list looking for
a specific name (of a specified length, not NUL terminated) in a specific
member of the listed objects, which must be a NUL-terminated const char *.
Again this is a good pattern that's encouraged by use of lws_tokenize
to recover the name we're looking for.

So it leads to the helper that can cleanly search for a listed object of the
right name from an owner, and return the typed object pointer or NULL, from a
length-specified string.
This commit is contained in:
Andy Green 2020-07-09 13:48:41 +01:00
parent 6b3221ffc1
commit 1ae6ce37d3
4 changed files with 67 additions and 1 deletions

View file

@ -245,6 +245,21 @@ LWS_VISIBLE LWS_EXTERN void
lws_dll2_add_sorted(lws_dll2_t *d, lws_dll2_owner_t *own,
int (*compare)(const lws_dll2_t *d, const lws_dll2_t *i));
LWS_VISIBLE LWS_EXTERN void *
_lws_dll2_search_sz_pl(lws_dll2_owner_t *own, const char *name, size_t namelen,
size_t dll2_ofs, size_t ptr_ofs);
/*
* Searches objects in an owner list linearly and returns one with a given
* member C-string matching a supplied length-provided string if it exists, else
* NULL.
*/
#define lws_dll2_search_sz_pl(own, name, namelen, type, membd2list, membptr) \
((type *)_lws_dll2_search_sz_pl(own, name, namelen, \
offsetof(type, membd2list), \
offsetof(type, membptr)))
#if defined(_DEBUG)
void
lws_dll2_describe(struct lws_dll2_owner *owner, const char *desc);

View file

@ -209,6 +209,25 @@ lws_dll2_add_sorted(lws_dll2_t *d, lws_dll2_owner_t *own,
lws_dll2_add_tail(d, own);
}
void *
_lws_dll2_search_sz_pl(lws_dll2_owner_t *own, const char *name, size_t namelen,
size_t dll2_ofs, size_t ptr_ofs)
{
lws_start_foreach_dll(struct lws_dll2 *, p, lws_dll2_get_head(own)) {
uint8_t *ref = ((uint8_t *)p) - dll2_ofs;
/*
* We have to read the const char * at the computed place and
* the string is where that points
*/
const char *str = *((const char **)(ref + ptr_ofs));
if (str && !strncmp(str, name, namelen) && !str[namelen])
return (void *)ref;
} lws_end_foreach_dll(p);
return NULL;
}
#if defined(_DEBUG)
void

View file

@ -256,7 +256,7 @@ lws_struct_default_lejp_cb(struct lejp_ctx *ctx, char reason)
return 1;
}
lwsl_notice("%s: created '%s' object size %d\n", __func__,
lwsl_info("%s: created '%s' object size %d\n", __func__,
pmap->colname, (int)pmap->aux);
if (pmap->type == LSMT_LIST) {

View file

@ -597,6 +597,38 @@ done:
free(buf);
}
{
struct x { lws_dll2_t list; const char *sz; };
struct x x1, x2, *xp;
lws_dll2_owner_t o;
lws_dll2_owner_clear(&o);
memset(&x1, 0, sizeof(x1));
memset(&x2, 0, sizeof(x2));
x1.sz = "nope";
x2.sz = "yes";
lws_dll2_add_tail(&x1.list, &o);
lws_dll2_add_tail(&x2.list, &o);
xp = lws_dll2_search_sz_pl(&o, "yes", 3, struct x, list, sz);
if (xp != &x2) {
lwsl_err("%s: 1 xp %p\n", __func__, xp);
goto bail;
}
xp = lws_dll2_search_sz_pl(&o, "nope", 4, struct x, list, sz);
if (xp != &x1) {
lwsl_err("%s: 2 xp %p\n", __func__, xp);
goto bail;
}
xp = lws_dll2_search_sz_pl(&o, "wrong", 4, struct x, list, sz);
if (xp) {
lwsl_err("%s: 3 xp %p\n", __func__, xp);
goto bail;
}
}
lwsl_user("Completed: PASS\n");