Commit 253e7c8e authored by Geoff Simmons's avatar Geoff Simmons

source code re-organization:

- en-/decoding implementation details in separate sources
- enforce the en-/decode interfaces with typedefs
parent 5f522459
......@@ -6,7 +6,11 @@ vmod_LTLIBRARIES = libvmod_convert.la
libvmod_convert_la_LDFLAGS = -module -export-dynamic -avoid-version -shared
libvmod_convert_la_SOURCES = \
vmod_convert.c
vmod_convert.c \
vmod_convert.h \
id.c \
base64.c \
hex.c
nodist_libvmod_convert_la_SOURCES = \
vcc_if.c \
......
/*-
* Copyright 2015-2016 UPLEX - Nils Goroll Systemoptimierung
* All rights reserved.
*
* Authors: Nils Goroll <nils.goroll@uplex.de>
* Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdio.h>
#include "vmod_convert.h"
#include "vas.h"
struct b64_state_s {
unsigned magic;
#define B64_STATE_MAGIC 0xc0b64b64
unsigned char bytes[2];
ssize_t l;
};
static struct b64_alphabet {
char *b64;
char i64[256];
int padding;
} b64_alphabet[__MAX_ENCODING];
static void
alpha_init(struct b64_alphabet *alpha)
{
int i;
const char *p;
for (i = 0; i < 256; i++)
alpha->i64[i] = -1;
for (p = alpha->b64, i = 0; *p; p++, i++)
alpha->i64[(int)*p] = (char)i;
if (alpha->padding)
alpha->i64[alpha->padding] = 0;
}
void
base64_init(void)
{
b64_alphabet[BASE64].b64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
"ghijklmnopqrstuvwxyz0123456789+/";
b64_alphabet[BASE64].padding = '=';
b64_alphabet[BASE64URL].b64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
"ghijklmnopqrstuvwxyz0123456789-_";
b64_alphabet[BASE64URL].padding = '=';
b64_alphabet[BASE64URLNOPAD].b64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
"ghijklmnopqrstuvwxyz0123456789-_";
b64_alphabet[BASE64URLNOPAD].padding = 0;
alpha_init(&b64_alphabet[BASE64]);
alpha_init(&b64_alphabet[BASE64URL]);
alpha_init(&b64_alphabet[BASE64URLNOPAD]);
}
/*
* Base64-encode *in (size: inlen) into the blob supplied as rblob. If
* there is insufficient space, it will bail out and return
* NULL. Otherwise, it will null-terminate and return the blob.
* The enc argument specifies the alphabet and whether padding is used.
* Inspired heavily by gnulib/Simon Josefsson (as referenced in RFC4648)
*
* XXX: tmp[] and idx are used to ensure the reader (and author) retains
* XXX: a limited amount of sanity. They are strictly speaking not
* XXX: necessary, if you don't mind going crazy.
*/
ssize_t
base64_encode(const enum encoding enc, char *restrict const buf,
const size_t maxlen, const char *restrict const inbuf,
const size_t inlength)
{
struct b64_alphabet *alpha = &b64_alphabet[enc];
char *p = buf;
const char *in = inbuf;
size_t outlen = maxlen, inlen = inlength;
unsigned char tmp[3], idx;
AN(buf);
if (in == NULL || inlen == 0)
return 0;
if (outlen < base64_encode_l(inlen))
return -1;
while (1) {
assert(inlen);
assert(outlen > 3);
tmp[0] = (unsigned char) in[0];
tmp[1] = (unsigned char) in[1];
tmp[2] = (unsigned char) in[2];
*p++ = alpha->b64[(tmp[0] >> 2) & 0x3f];
idx = (tmp[0] << 4);
if (inlen > 1)
idx += (tmp[1] >> 4);
idx &= 0x3f;
*p++ = alpha->b64[idx];
if (inlen > 1) {
idx = (tmp[1] << 2);
if (inlen > 2)
idx += tmp[2] >> 6;
idx &= 0x3f;
*p++ = alpha->b64[idx];
} else {
if (alpha->padding)
*p++ = alpha->padding;
}
if (inlen > 2) {
*p++ = alpha->b64[tmp[2] & 0x3f];
} else {
if (alpha->padding)
*p++ = alpha->padding;
}
/*
* XXX: Only consume 4 bytes, but since we need a fifth for
* XXX: NULL later on, we might as well test here.
*/
assert(outlen >= 5);
outlen -= 4;
if (inlen < 4)
break;
inlen -= 3;
in += 3;
}
assert(outlen > 0);
return p - buf;
}
/*-
* Copyright 2015-2016 UPLEX - Nils Goroll Systemoptimierung
* All rights reserved.
*
* Authors: Nils Goroll <nils.goroll@uplex.de>
* Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "vmod_convert.h"
#include "vas.h"
static const char hex_alphabet[][16] = {
"0123456789abcdef",
"0123456789ABCDEF"
};
ssize_t
hex_encode(const enum encoding enc, char *restrict const buf,
const size_t maxlen, const char *restrict const in,
const size_t inlen)
{
char *p = buf;
const char *alphabet = hex_alphabet[0];
AN(buf);
if (in == NULL || inlen == 0)
return 0;
if (maxlen < hex_encode_l(inlen))
return -1;
if (enc != HEXLC)
alphabet = hex_alphabet[1];
for (int i = 0; i < inlen; i++) {
*p++ = alphabet[(in[i] & 0xf0) >> 4];
*p++ = alphabet[in[i] & 0x0f];
}
return p - buf;
}
/*-
* Copyright 2015-2016 UPLEX - Nils Goroll Systemoptimierung
* All rights reserved.
*
* Authors: Nils Goroll <nils.goroll@uplex.de>
* Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <string.h>
#include "vmod_convert.h"
#include "vrt.h"
#include "vas.h"
ssize_t
id_encode(const enum encoding enc, char *restrict const buf,
const size_t maxlen, const char *restrict const in,
const size_t inlen)
{
(void) enc;
AN(buf);
if (maxlen < inlen + 1)
return -1;
if (in == NULL || inlen == 0)
return 0;
memcpy(buf, in, inlen);
return inlen;
}
ssize_t
id_decode(const enum encoding enc, char *restrict const buf,
const size_t maxlen, const char *restrict const p, va_list ap)
{
const char *next;
char *dest = buf;
size_t len, outlen = 0;
(void) enc;
AN(buf);
if (p == vrt_magic_string_end)
return 0;
SKIP_EMPTY(next, ap);
if (next == vrt_magic_string_end && (p == NULL || *p == '\0'))
return 0;
if (p != NULL && *p != '\0') {
if ((len = strlen(p)) > maxlen)
return -1;
memcpy(buf, p, len);
outlen = len;
dest += len;
}
while (next != vrt_magic_string_end) {
len = strlen(next);
if ((outlen += len) > maxlen)
return -1;
memcpy(dest, next, len);
dest += len;
SKIP_EMPTY(next, ap);
}
return outlen;
}
#include <stdio.h>
#include <stdlib.h>
/*-
* Copyright 2015-2016 UPLEX - Nils Goroll Systemoptimierung
* All rights reserved.
*
* Authors: Nils Goroll <nils.goroll@uplex.de>
* Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "vcl.h"
#include "vrt.h"
#include "vcc_if.h"
#include "parse_encoding.h"
#include "vmod_convert.h"
#include "wb.h"
#define SKIP_EMPTY(next, ap) \
do { \
next = va_arg((ap), const char *); \
} while ((next) == NULL || *(next) == '\0')
/*
* SAFE LENGTH ESTIMATES
*/
#define base64_decode_l(l) ((l * 3 / 4) + 1)
#define base64_encode_l(l) (((((l * 4 / 3) + 3) / 4) * 4) + 1)
#define hex_encode_l(l) ((l * 2) + 1)
#define hex_decode_l(l) ((l / 2) + 1)
static const struct vmod_priv const null_blob[1] =
{
{
......@@ -31,38 +42,6 @@ static const struct vmod_priv const null_blob[1] =
}
};
struct b64_state_s {
uint32_t magic;
#define B64_STATE_MAGIC 0xc0b64b64
unsigned char bytes[2];
ssize_t l;
};
static struct b64_alphabet {
char *b64;
char i64[256];
int padding;
} b64_alphabet[__MAX_ENCODING];
static const char hex_alphabet[][16] = {
"0123456789abcdef",
"0123456789ABCDEF"
};
static void
alpha_init(struct b64_alphabet *alpha)
{
int i;
const char *p;
for (i = 0; i < 256; i++)
alpha->i64[i] = -1;
for (p = alpha->b64, i = 0; *p; p++, i++)
alpha->i64[(int)*p] = (char)i;
if (alpha->padding)
alpha->i64[alpha->padding] = 0;
}
int __match_proto__(vmod_event_f)
event(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e event)
{
......@@ -71,195 +50,10 @@ event(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e event)
if (event != VCL_EVENT_LOAD)
return 0;
b64_alphabet[BASE64].b64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
"ghijklmnopqrstuvwxyz0123456789+/";
b64_alphabet[BASE64].padding = '=';
b64_alphabet[BASE64URL].b64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
"ghijklmnopqrstuvwxyz0123456789-_";
b64_alphabet[BASE64URL].padding = '=';
b64_alphabet[BASE64URLNOPAD].b64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
"ghijklmnopqrstuvwxyz0123456789-_";
b64_alphabet[BASE64URLNOPAD].padding = 0;
alpha_init(&b64_alphabet[BASE64]);
alpha_init(&b64_alphabet[BASE64URL]);
alpha_init(&b64_alphabet[BASE64URLNOPAD]);
base64_init();
return (0);
}
static ssize_t
id_encode(const enum encoding enc, char *restrict const buf,
const size_t maxlen, const char *restrict const in,
const size_t inlen)
{
(void) enc;
AN(buf);
if (maxlen < inlen + 1)
return -1;
if (in == NULL || inlen == 0)
return 0;
memcpy(buf, in, inlen);
return inlen;
}
static ssize_t
id_decode(const enum encoding enc, char *restrict const buf,
const size_t maxlen, const char *restrict const p, va_list ap)
{
const char *next;
char *dest = buf;
size_t len, outlen = 0;
(void) enc;
AN(buf);
if (p == vrt_magic_string_end)
return 0;
SKIP_EMPTY(next, ap);
if (next == vrt_magic_string_end && (p == NULL || *p == '\0'))
return 0;
if (p != NULL && *p != '\0') {
if ((len = strlen(p)) > maxlen)
return -1;
memcpy(buf, p, len);
outlen = len;
dest += len;
}
while (next != vrt_magic_string_end) {
len = strlen(next);
if ((outlen += len) > maxlen)
return -1;
memcpy(dest, next, len);
dest += len;
SKIP_EMPTY(next, ap);
}
return outlen;
}
/*
* Base64-encode *in (size: inlen) into the blob supplied as rblob. If
* there is insufficient space, it will bail out and return
* NULL. Otherwise, it will null-terminate and return the blob.
* The enc argument specifies the alphabet and whether padding is used.
* Inspired heavily by gnulib/Simon Josefsson (as referenced in RFC4648)
*
* XXX: tmp[] and idx are used to ensure the reader (and author) retains
* XXX: a limited amount of sanity. They are strictly speaking not
* XXX: necessary, if you don't mind going crazy.
*/
static ssize_t
base64_encode(const enum encoding enc, char *restrict const buf,
const size_t maxlen, const char *restrict const inbuf,
const size_t inlength)
{
struct b64_alphabet *alpha = &b64_alphabet[enc];
char *p = buf;
const char *in = inbuf;
size_t outlen = maxlen, inlen = inlength;
unsigned char tmp[3], idx;
AN(buf);
if (in == NULL || inlen == 0)
return 0;
if (outlen < base64_encode_l(inlen))
return -1;
while (1) {
assert(inlen);
assert(outlen > 3);
tmp[0] = (unsigned char) in[0];
tmp[1] = (unsigned char) in[1];
tmp[2] = (unsigned char) in[2];
*p++ = alpha->b64[(tmp[0] >> 2) & 0x3f];
idx = (tmp[0] << 4);
if (inlen > 1)
idx += (tmp[1] >> 4);
idx &= 0x3f;
*p++ = alpha->b64[idx];
if (inlen > 1) {
idx = (tmp[1] << 2);
if (inlen > 2)
idx += tmp[2] >> 6;
idx &= 0x3f;
*p++ = alpha->b64[idx];
} else {
if (alpha->padding)
*p++ = alpha->padding;
}
if (inlen > 2) {
*p++ = alpha->b64[tmp[2] & 0x3f];
} else {
if (alpha->padding)
*p++ = alpha->padding;
}
/*
* XXX: Only consume 4 bytes, but since we need a fifth for
* XXX: NULL later on, we might as well test here.
*/
assert(outlen >= 5);
outlen -= 4;
if (inlen < 4)
break;
inlen -= 3;
in += 3;
}
assert(outlen > 0);
return p - buf;
}
/*
* en/decoders need to work for the string_list vargs case (implicit length) as
* well as for the blob case (explicit length). Fortunately, the blob case is
* not varadic, so we can assume just one length argument _or_ varags
*
* rblob: alloc additional whitespace so any result can also be (safely)
* used as a string.
*/
static ssize_t
hex_encode(const enum encoding enc, char *restrict const buf,
const size_t maxlen, const char *restrict const in,
const size_t inlen)
{
char *p = buf;
const char *alphabet = hex_alphabet[0];
AN(buf);
if (in == NULL || inlen == 0)
return 0;
if (maxlen < hex_encode_l(inlen))
return -1;
if (enc != HEXLC)
alphabet = hex_alphabet[1];
for (int i = 0; i < inlen; i++) {
*p++ = alphabet[(in[i] & 0xf0) >> 4];
*p++ = alphabet[in[i] & 0x0f];
}
return p - buf;
}
static inline VCL_STRING
concat_va(struct ws *ws, const char *p, va_list ap)
{
......@@ -297,7 +91,7 @@ concat_va(struct ws *ws, const char *p, va_list ap)
return wb_finish(&wb, NULL);
}
static size_t
static inline size_t
decode_l_va(enum encoding dec, const char * const p, va_list ap)
{
size_t len = 0;
......
/*-
* Copyright 2015-2016 UPLEX - Nils Goroll Systemoptimierung
* All rights reserved.
*
* Authors: Nils Goroll <nils.goroll@uplex.de>
* Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdlib.h>
#include <stdarg.h>
#include "parse_encoding.h"
#define SKIP_EMPTY(next, ap) \
do { \
next = va_arg((ap), const char *); \
} while ((next) == NULL || *(next) == '\0')
/*
* SAFE LENGTH ESTIMATES
*/
#define base64_decode_l(l) ((l * 3 / 4) + 1)
#define base64_encode_l(l) (((((l * 4 / 3) + 3) / 4) * 4) + 1)
#define hex_encode_l(l) ((l * 2) + 1)
#define hex_decode_l(l) ((l / 2) + 1)
/*
* General interface for an encoder: encode the data at in of length inlen
* into a null-terminated string at buf, and return the length of the
* encoding.
*
* enc: encoding enum (from parse_encoding.h)
* buf: destination of the encoded string
* maxlen: maximum length available at buf
* in: source of data to be encoded
* inlen: length of data to be encoded
*
* The regions pointed to by buf and in MUST NOT overlap (this is the
* contract imposed by restrict).
* An encoder SHALL NOT append the terminating null byte (this must
* be done by the caller).
*
* Returns:
* -1, if there is insufficient space at buf, *including* space for the
* terminating null byte
* 0, if the length of the encoding is 0 -- the caller should return
* the static constant empty string (literal "")
* otherwise, the number of bytes written (note that this does not
* include any terminating null byte)
*/
typedef
ssize_t encode_f(const enum encoding enc, char *restrict const buf,
const size_t maxlen, const char *restrict const in,
const size_t inlen);
/*
* General interface for a decoder: decode the concatenation of strings
* in p and ap (obtained from a STRING_LIST) into buf, and return the
* length of decoded data.
*
* dec: decoding enum (from parse_encoding.h)
* buf: destination of the decoded data
* maxlen: maximum length available at buf
* p, ap: strings obtained from a VCL STRING_LIST
*
* The regions pointed to by buf and any of the strings in p or ap MUST
* NOT overlap (per restrict).
* Note that the p,ap list is terminated by vrt_magic_string_end, and
* any member of the list may be NULL or empty.
*
* Returns:
* -1, if there is insufficient space at buf, or if the decoding is
* invalid (XXX: set errno to ENOMEM or EINVALID)
* 0, if the length of the decoding is 0 -- the caller should return
* a static constant empty BLOB
* otherwise, the number of bytes written
*/
typedef
ssize_t decode_f(const enum encoding dec, char *restrict const buf,
const size_t maxlen, const char *restrict const p, va_list ap);
/* id.c */
encode_f id_encode;
decode_f id_decode;
/* base64.c */
void base64_init(void);
encode_f base64_encode;
/* hex.c */
encode_f hex_encode;
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