Commit 8e1e5501 authored by Geoff Simmons's avatar Geoff Simmons

avoid copying for IDENTITY decode if possible

Patch from Nils
parent be35b28f
...@@ -325,9 +325,70 @@ vmod_blob__fini(struct vmod_blobcode_blob **blobp) ...@@ -325,9 +325,70 @@ vmod_blob__fini(struct vmod_blobcode_blob **blobp)
/* Functions */ /* Functions */
static inline const char *
find_nonempty_va(const char *restrict *p, va_list ap) {
const char *q;
/* find first non-empty vararg */
for (; *p == vrt_magic_string_end || *p == NULL || **p == '\0';
*p = va_arg(ap, const char *))
if (*p == vrt_magic_string_end)
return (vrt_magic_string_end);
/* find next non-empty vararg */
for (q = va_arg(ap, const char *);
q != vrt_magic_string_end && (q == NULL || *q == '\0');
q = va_arg(ap, const char *))
;
return (q);
}
/*
* special case: we can avoid copying for identity decode if we need to
* deal with a single vararg only - in which case we just have the blob
* point to the input string
*/
static VCL_BLOB
decode_id_inplace(struct vmod_priv *b, VCL_INT n, const char *restrict p,
va_list ap) {
const char *q;
int l;
if (n == 0)
return null_blob;
q = find_nonempty_va(&p, ap);
if (p == vrt_magic_string_end)
return null_blob;
if (q == vrt_magic_string_end) {
/* can use in-place decode */
l = strlen(p);
if (n > 0 && n < l)
l = n;
b->priv = (char *)p;
b->len = l;
b->free = NULL;
return (b);
}
if (n == -1)
return NULL;
l = strlen(p);
if (n > l)
return NULL;
b->priv = (char *)p;
b->len = n;
b->free = NULL;
return (b);
}
static VCL_BLOB static VCL_BLOB
decode(VRT_CTX, VCL_INT n, VCL_ENUM decs, const char *restrict const p, decode(VRT_CTX, VCL_INT n, VCL_ENUM decs,
va_list ap) { const char *restrict const p, va_list ap) {
enum encoding dec = parse_encoding(decs); enum encoding dec = parse_encoding(decs);
struct wb_s wb; struct wb_s wb;
struct vmod_priv *b; struct vmod_priv *b;
...@@ -348,6 +409,18 @@ decode(VRT_CTX, VCL_INT n, VCL_ENUM decs, const char *restrict const p, ...@@ -348,6 +409,18 @@ decode(VRT_CTX, VCL_INT n, VCL_ENUM decs, const char *restrict const p,
ERRNOMEM(ctx, "cannot decode"); ERRNOMEM(ctx, "cannot decode");
return NULL; return NULL;
} }
if (dec == IDENTITY) {
va_list aq;
va_copy(aq, ap);
const struct vmod_priv *bb = decode_id_inplace(b, n, p, aq);
va_end(aq);
if (bb == null_blob)
WS_Reset(ctx->ws, snap);
if (bb == b)
return bb;
}
if (wb_create(ctx->ws, &wb) == NULL) { if (wb_create(ctx->ws, &wb) == NULL) {
WS_Reset(ctx->ws, snap); WS_Reset(ctx->ws, snap);
ERRNOMEM(ctx, "cannot decode"); ERRNOMEM(ctx, "cannot decode");
...@@ -401,9 +474,8 @@ vmod_decode_n(VRT_CTX, VCL_INT n, VCL_ENUM decs, const char *p, ...) { ...@@ -401,9 +474,8 @@ vmod_decode_n(VRT_CTX, VCL_INT n, VCL_ENUM decs, const char *p, ...) {
return (r); return (r);
} }
VCL_STRING __match_proto__(td_blobcode_encode) static VCL_STRING
vmod_encode(VRT_CTX, VCL_ENUM encs, VCL_BLOB b) { encode(VRT_CTX, enum encoding enc, VCL_BLOB b) {
enum encoding enc = parse_encoding(encs);
struct wb_s wb; struct wb_s wb;
ssize_t len; ssize_t len;
...@@ -439,6 +511,12 @@ vmod_encode(VRT_CTX, VCL_ENUM encs, VCL_BLOB b) { ...@@ -439,6 +511,12 @@ vmod_encode(VRT_CTX, VCL_ENUM encs, VCL_BLOB b) {
return wb_finish(&wb, NULL); return wb_finish(&wb, NULL);
} }
VCL_STRING __match_proto__(td_blobcode_encode)
vmod_encode(VRT_CTX, VCL_ENUM encs, VCL_BLOB b) {
enum encoding enc = parse_encoding(encs);
return encode(ctx, enc, b);
}
static VCL_STRING static VCL_STRING
transcode(VRT_CTX, VCL_INT n, VCL_ENUM decs, VCL_ENUM encs, transcode(VRT_CTX, VCL_INT n, VCL_ENUM decs, VCL_ENUM encs,
const char *restrict const p, va_list ap) { const char *restrict const p, va_list ap) {
...@@ -458,6 +536,17 @@ transcode(VRT_CTX, VCL_INT n, VCL_ENUM decs, VCL_ENUM encs, ...@@ -458,6 +536,17 @@ transcode(VRT_CTX, VCL_INT n, VCL_ENUM decs, VCL_ENUM encs,
AENC(dec); AENC(dec);
AENC(enc); AENC(enc);
if (dec == IDENTITY) {
struct vmod_priv b;
va_copy(aq, ap);
const struct vmod_priv *bb = decode_id_inplace(&b, n, p, aq);
va_end(aq);
if (bb != NULL) {
VCL_STRING r = encode(ctx, enc, bb);
return (r);
}
}
/* /*
* Allocate space for the decoded blob on the stack * Allocate space for the decoded blob on the stack
* ignoring the limitation imposed by n * ignoring the limitation imposed by n
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment