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)
/* 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
decode(VRT_CTX, VCL_INT n, VCL_ENUM decs, const char *restrict const p,
va_list ap) {
decode(VRT_CTX, VCL_INT n, VCL_ENUM decs,
const char *restrict const p, va_list ap) {
enum encoding dec = parse_encoding(decs);
struct wb_s wb;
struct vmod_priv *b;
......@@ -348,6 +409,18 @@ decode(VRT_CTX, VCL_INT n, VCL_ENUM decs, const char *restrict const p,
ERRNOMEM(ctx, "cannot decode");
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) {
WS_Reset(ctx->ws, snap);
ERRNOMEM(ctx, "cannot decode");
......@@ -401,9 +474,8 @@ vmod_decode_n(VRT_CTX, VCL_INT n, VCL_ENUM decs, const char *p, ...) {
return (r);
}
VCL_STRING __match_proto__(td_blobcode_encode)
vmod_encode(VRT_CTX, VCL_ENUM encs, VCL_BLOB b) {
enum encoding enc = parse_encoding(encs);
static VCL_STRING
encode(VRT_CTX, enum encoding enc, VCL_BLOB b) {
struct wb_s wb;
ssize_t len;
......@@ -439,6 +511,12 @@ vmod_encode(VRT_CTX, VCL_ENUM encs, VCL_BLOB b) {
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
transcode(VRT_CTX, VCL_INT n, VCL_ENUM decs, VCL_ENUM encs,
const char *restrict const p, va_list ap) {
......@@ -458,6 +536,17 @@ transcode(VRT_CTX, VCL_INT n, VCL_ENUM decs, VCL_ENUM encs,
AENC(dec);
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
* 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