Skip to content

Commit f9242a5

Browse files
committed
lejp: unified strings
Adds helpers that transform lejp-processed chunked strings into reallocated single linear strings with a terminating NUL, in the same ac.
1 parent 52ced53 commit f9242a5

2 files changed

Lines changed: 80 additions & 0 deletions

File tree

include/libwebsockets/lws-lejp.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,20 @@ struct _lejp_parsing_stack {
217217
uint8_t path_match;
218218
};
219219

220+
typedef struct lejp_string_piece {
221+
struct lejp_string_piece *next;
222+
const char *piece;
223+
size_t len;
224+
} lejp_string_piece_t;
225+
226+
typedef struct {
227+
lejp_string_piece_t *sph;
228+
lejp_string_piece_t **sp_next;
229+
int pieces;
230+
size_t asl;
231+
char *fp;
232+
} lejp_string_unifier_t;
233+
220234
struct lejp_ctx {
221235

222236
/* sorted by type for most compact alignment
@@ -234,6 +248,8 @@ struct lejp_ctx {
234248
char path[LEJP_MAX_PATH];
235249
char buf[LEJP_STRING_CHUNK + 1];
236250

251+
lejp_string_unifier_t su;
252+
237253
/* size_t */
238254

239255
size_t path_stride; /* 0 means default ptr size, else stride */
@@ -306,4 +322,10 @@ lejp_get_wildcard(struct lejp_ctx *ctx, int wildcard, char *dest, int len);
306322

307323
LWS_VISIBLE LWS_EXTERN const char *
308324
lejp_error_to_string(int e);
325+
326+
LWS_VISIBLE LWS_EXTERN int
327+
lejp_string_unify(struct lejp_ctx *ctx, struct lwsac **ac);
328+
329+
LWS_VISIBLE LWS_EXTERN int
330+
lejp_string_unify_part(struct lejp_ctx *ctx, struct lwsac **ac, char reason);
309331
//@}

lib/misc/lejp.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,3 +952,61 @@ lejp_error_to_string(int e)
952952
return parser_errs[e];
953953
}
954954

955+
int
956+
lejp_string_unify(struct lejp_ctx *ctx, struct lwsac **ac)
957+
{
958+
char *p;
959+
960+
if (ctx->su.pieces == 1)
961+
return 0;
962+
963+
ctx->su.fp = lwsac_use(ac, ctx->su.asl + 1u, 512);
964+
if (!ctx->su.fp)
965+
return 1;
966+
967+
p = ctx->su.fp;
968+
while (ctx->su.sph) {
969+
memcpy(p, ctx->su.sph->piece, ctx->su.sph->len);
970+
p += ctx->su.sph->len;
971+
ctx->su.sph = ctx->su.sph->next;
972+
}
973+
*p = '\0';
974+
975+
return 0;
976+
}
977+
978+
int
979+
lejp_string_unify_part(struct lejp_ctx *ctx, struct lwsac **ac, char reason)
980+
{
981+
if (reason == LEJPCB_VAL_STR_START) {
982+
memset(&ctx->su, 0, sizeof(ctx->su));
983+
ctx->su.sp_next = &ctx->su.sph;
984+
}
985+
986+
if (
987+
(reason == LEJPCB_VAL_STR_START && ctx->npos) ||
988+
(reason == LEJPCB_VAL_STR_CHUNK && ctx->npos) ||
989+
(reason == LEJPCB_VAL_STR_END)) {
990+
lejp_string_piece_t *s;
991+
992+
ctx->su.fp = lwsac_use(ac, ctx->npos + 1u, 512);
993+
if (!ctx->su.fp)
994+
return 1;
995+
memcpy(ctx->su.fp, ctx->buf, ctx->npos);
996+
ctx->su.fp[ctx->npos] = '\0';
997+
s = lwsac_use_zero(ac, sizeof(*s), 512);
998+
if (!s)
999+
return 1;
1000+
*ctx->su.sp_next = s;
1001+
s->piece = ctx->su.fp;
1002+
s->len = ctx->npos;
1003+
ctx->su.asl += ctx->npos;
1004+
ctx->su.sp_next = &s->next;
1005+
1006+
if (reason == LEJPCB_VAL_STR_END)
1007+
ctx->su.sp_next = &ctx->su.sph;
1008+
}
1009+
1010+
return 0;
1011+
}
1012+

0 commit comments

Comments
 (0)