diff --git a/include/libwebsockets/lws-dll2.h b/include/libwebsockets/lws-dll2.h index 367c887de..151e7fcd1 100644 --- a/include/libwebsockets/lws-dll2.h +++ b/include/libwebsockets/lws-dll2.h @@ -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); diff --git a/lib/core/lws_dll2.c b/lib/core/lws_dll2.c index 7556695db..adca56590 100644 --- a/lib/core/lws_dll2.c +++ b/lib/core/lws_dll2.c @@ -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 diff --git a/lib/misc/lws-struct-lejp.c b/lib/misc/lws-struct-lejp.c index c808adad6..f083c9803 100644 --- a/lib/misc/lws-struct-lejp.c +++ b/lib/misc/lws-struct-lejp.c @@ -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) { diff --git a/minimal-examples/api-tests/api-test-lws_struct-json/main.c b/minimal-examples/api-tests/api-test-lws_struct-json/main.c index 6148d607b..d6d02ae13 100644 --- a/minimal-examples/api-tests/api-test-lws_struct-json/main.c +++ b/minimal-examples/api-tests/api-test-lws_struct-json/main.c @@ -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");