joes 2003/01/24 11:15:08
Modified: src apreq_cookie.h apreq_cookie.c apreq_tables.c
apreq_tables.h apreq.h apreq.c apreq_params.h
apreq_params.c
Log:
Symmetrize the APIs for cookies & params.
Revision Changes Path
1.5 +7 -15 httpd-apreq-2/src/apreq_cookie.h
Index: apreq_cookie.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_cookie.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- apreq_cookie.h 24 Jan 2003 04:29:09 -0000 1.4
+++ apreq_cookie.h 24 Jan 2003 19:15:07 -0000 1.5
@@ -45,14 +45,6 @@
/**
- * returns the current context jar.
- *
- *
- */
-APREQ_DECLARE(apreq_jar_t *) apreq_jar(void *ctx);
-#define apreq_jar(r) apreq_jar_parse(r,NULL)
-
-/**
* Returns the number of cookies in the jar.
*
* @param jar The cookie jar.
@@ -70,8 +62,8 @@
* @param name The name of the desired cookie.
*/
-apreq_cookie_t *apreq_jar_get(apreq_jar_t *jar, char *name);
-#define apreq_jar_get(j,k) apreq_value_to_cookie(apreq_char_to_value( \
+apreq_cookie_t *apreq_cookie(const apreq_jar_t *jar, const char *name);
+#define apreq_cookie(j,k) apreq_value_to_cookie(apreq_char_to_value( \
apreq_table_get(j,k)))
/**
@@ -100,7 +92,7 @@
*/
-apreq_jar_t *apreq_jar_parse(void *ctx, const char *data);
+APREQ_DECLARE(apreq_jar_t *) apreq_jar(void *ctx, const char *data);
/**
* Returns a new cookie, made from the argument list.
@@ -133,8 +125,8 @@
* @param c The cookie.
* @param p The pool.
*/
-APREQ_DECLARE(const char*) apreq_cookie_as_string(const apreq_cookie_t *c,
- apr_pool_t *p);
+APREQ_DECLARE(const char*) apreq_cookie_as_string(apr_pool_t *p,
+ const apreq_cookie_t *c);
/**
* Same functionality as apreq_cookie_as_string. Stores the string
@@ -168,7 +160,7 @@
*
* @param c The cookie.
*/
-APREQ_DECLARE(apr_status_t) apreq_cookie_bake(apreq_cookie_t *c);
+APREQ_DECLARE(apr_status_t) apreq_cookie_bake(const apreq_cookie_t *c);
/* XXX: how about baking whole cookie jars, too ??? */
@@ -177,7 +169,7 @@
*
* @param c The cookie.
*/
-APREQ_DECLARE(apr_status_t) apreq_cookie_bake2(apreq_cookie_t *c);
+APREQ_DECLARE(apr_status_t) apreq_cookie_bake2(const apreq_cookie_t *c);
APREQ_DECLARE(apreq_cookie_version_t) apreq_cookie_ua_version(void *ctx);
1.6 +16 -20 httpd-apreq-2/src/apreq_cookie.c
Index: apreq_cookie.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_cookie.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- apreq_cookie.c 24 Jan 2003 04:29:09 -0000 1.5
+++ apreq_cookie.c 24 Jan 2003 19:15:07 -0000 1.6
@@ -64,10 +64,10 @@
return apreq_jar_items(jar);
}
-APREQ_DECLARE(apreq_cookie_t *) (apreq_jar_get)(apreq_jar_t *jar,
- char *name)
+APREQ_DECLARE(apreq_cookie_t *) (apreq_cookie)(const apreq_jar_t *jar,
+ const char *name)
{
- return apreq_jar_get(jar,name);
+ return apreq_cookie(jar,name);
}
APREQ_DECLARE(void) (apreq_jar_add)(apreq_jar_t *jar,
@@ -82,7 +82,7 @@
if ( c->version == NETSCAPE )
c->time.expires = apreq_expires(apreq_env_pool(c->ctx),
time_str,
- APREQ_EXPIRES_COOKIE);
+ NSCOOKIE);
else
c->time.max_age = apreq_atol(time_str);
}
@@ -92,14 +92,14 @@
const apreq_cookie_t *c = apreq_value_to_cookie(
apreq_char_to_value(val));
- return c->version == NETSCAPE; /* 0 -> found, stop.
+ return c->version == NETSCAPE; /* 0 -> non-netscape cookie found, stop.
1 -> not found, keep going. */
}
APREQ_DECLARE(apreq_cookie_version_t) apreq_cookie_ua_version(void *ctx)
{
if (apreq_env_cookie2(ctx) == NULL) {
- apreq_jar_t *j = apreq_jar_parse(ctx, NULL);
+ apreq_jar_t *j = apreq_jar(ctx, NULL);
if (j == NULL || apreq_jar_nelts(j) == 0)
return APREQ_COOKIE_VERSION;
@@ -275,8 +275,8 @@
return APR_SUCCESS;
}
-APREQ_DECLARE(apreq_jar_t *) apreq_jar_parse(void *ctx,
- const char *data)
+APREQ_DECLARE(apreq_jar_t *) apreq_jar(void *ctx,
+ const char *data)
{
apr_pool_t *p = apreq_env_pool(ctx);
@@ -347,7 +347,7 @@
switch (*data) {
case 0:
- /* this is the normal exit point for apreq_cookie_parse */
+ /* this is the normal exit point for apreq_jar */
return j;
@@ -401,11 +401,6 @@
return j;
}
-APREQ_DECLARE(apreq_jar_t *) (apreq_jar)(void *ctx)
-{
- return apreq_jar(ctx);
-}
-
APREQ_DECLARE(int) apreq_cookie_serialize(const apreq_cookie_t *c,
char *buf, apr_size_t len)
{
@@ -471,8 +466,9 @@
}
-APREQ_DECLARE(const char*) apreq_cookie_as_string(const apreq_cookie_t *c,
- apr_pool_t *p)
+APREQ_DECLARE(const char*) apreq_cookie_as_string(apr_pool_t *p,
+ const apreq_cookie_t *c)
+
{
char s[APREQ_COOKIE_LENGTH];
int n = apreq_cookie_serialize(c, s, APREQ_COOKIE_LENGTH);
@@ -483,9 +479,9 @@
return NULL;
}
-APREQ_DECLARE(apr_status_t) apreq_cookie_bake(apreq_cookie_t *c)
+APREQ_DECLARE(apr_status_t) apreq_cookie_bake(const apreq_cookie_t *c)
{
- const char *s = apreq_cookie_as_string(c, apreq_env_pool(c->ctx));
+ const char *s = apreq_cookie_as_string(apreq_env_pool(c->ctx),c);
if (s == NULL) {
apreq_error(c->ctx, APR_ENAMETOOLONG, "Serialized cookie "
@@ -497,9 +493,9 @@
return apreq_env_set_cookie(c->ctx, s);
}
-APREQ_DECLARE(apr_status_t) apreq_cookie_bake2(apreq_cookie_t *c)
+APREQ_DECLARE(apr_status_t) apreq_cookie_bake2(const apreq_cookie_t *c)
{
- const char *s = apreq_cookie_as_string(c, apreq_env_pool(c->ctx));
+ const char *s = apreq_cookie_as_string(apreq_env_pool(c->ctx),c);
if ( s == NULL ) {
apreq_error(c->ctx, APR_ENAMETOOLONG, "Serialized cookie "
1.7 +5 -5 httpd-apreq-2/src/apreq_tables.c
Index: apreq_tables.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_tables.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- apreq_tables.c 24 Jan 2003 04:29:09 -0000 1.6
+++ apreq_tables.c 24 Jan 2003 19:15:07 -0000 1.7
@@ -550,7 +550,7 @@
}
APREQ_DECLARE(apreq_table_t *) apreq_table_copy(apr_pool_t *p,
- const apreq_table_t *t)
+ const apreq_table_t *t)
{
apreq_table_t *new = apr_palloc(p, sizeof *new);
@@ -575,8 +575,8 @@
return new;
}
-APREQ_DECLARE(apr_table_t *)apreq_table_export(const apreq_table_t *t,
- apr_pool_t *p)
+APREQ_DECLARE(apr_table_t *)apreq_table_export(apr_pool_t *p,
+ const apreq_table_t *t)
{
int idx;
apreq_table_entry_t *o = (apreq_table_entry_t *)t->a.elts;
@@ -841,8 +841,8 @@
}
-APREQ_DECLARE(apr_array_header_t *) apreq_table_values(const apreq_table_t
*t,
- apr_pool_t *p,
+APREQ_DECLARE(apr_array_header_t *) apreq_table_values(apr_pool_t *p,
+ const apreq_table_t
*t,
const char *key)
{
int idx;
1.6 +4 -4 httpd-apreq-2/src/apreq_tables.h
Index: apreq_tables.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_tables.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- apreq_tables.h 24 Jan 2003 04:29:09 -0000 1.5
+++ apreq_tables.h 24 Jan 2003 19:15:07 -0000 1.6
@@ -116,8 +116,8 @@
* @param p The pool to allocate the APR table from
* @param t The APREQ table to copy
*/
-APREQ_DECLARE(apr_table_t *) apreq_table_export(const apreq_table_t *t,
- apr_pool_t *p);
+APREQ_DECLARE(apr_table_t *) apreq_table_export(apr_pool_t *p,
+ const apreq_table_t *t);
/**
* Create an APREQ Table from an APR Table.
@@ -243,8 +243,8 @@
* only the first value of a multivalued entry is used.
*/
-APREQ_DECLARE(apr_array_header_t *) apreq_table_values(const apreq_table_t
*t,
- apr_pool_t *p,
+APREQ_DECLARE(apr_array_header_t *) apreq_table_values(apr_pool_t *p,
+ const apreq_table_t
*t,
const char *key);
/**
* Add an apreq_value_t to the table. If another value already exists
1.6 +14 -11 httpd-apreq-2/src/apreq.h
Index: apreq.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- apreq.h 24 Jan 2003 04:29:09 -0000 1.5
+++ apreq.h 24 Jan 2003 19:15:07 -0000 1.6
@@ -35,12 +35,6 @@
#define APREQ_MATCH_FULL 0
#define APREQ_MATCH_PART 1
-/* join modes */
-#define APREQ_JOIN_ESCAPE 1
-#define APREQ_JOIN_UNESCAPE 2
-#define APREQ_JOIN_URLENCODE 3
-#define APREQ_JOIN_QUOTE 4
-
/* status codes */
#define APREQ_OK 0
#define APREQ_CONTINUE 100
@@ -70,10 +64,11 @@
apreq_value_t *apreq_value_copy(apr_pool_t *p, const apreq_value_t *val);
apreq_value_t *apreq_value_merge(apr_pool_t *p, const apr_array_header_t
*arr);
+typedef enum { AS_IS, ENCODE, DECODE, QUOTE } apreq_join_t;
APREQ_DECLARE(const char *) apreq_join(apr_pool_t *p,
const char *sep,
const apr_array_header_t *arr,
- int mode);
+ apreq_join_t mode);
/* XXX: should we drop this and replace it with apreq_index ? */
char *apreq_memmem(char* hay, apr_off_t haylen,
@@ -84,8 +79,14 @@
/* url-escapes non-alphanumeric characters */
apr_size_t apreq_quote(char *dest, const char *src, const apr_size_t slen);
-apr_size_t apreq_escape(char *dest, const char *src, const apr_size_t slen);
-apr_ssize_t apreq_unescape(char *dest, const char *src, apr_size_t slen);
+apr_size_t apreq_encode(char *dest, const char *src, const apr_size_t slen);
+apr_ssize_t apreq_decode(char *dest, const char *src, apr_size_t slen);
+
+APREQ_DECLARE(char *) apreq_escape(apr_pool_t *p,
+ const char *src, const apr_size_t slen);
+
+APREQ_DECLARE(apr_ssize_t) apreq_unescape(char *str);
+#define apreq_unescape(str) apreq_decode(str,str,strlen(str))
/**
* Returns an RFC-822 formatted time string. Similar to ap_gm_timestr_822.
@@ -96,9 +97,11 @@
*/
/* returns date string, (time_str is offset from "now") formatted
- * either as an NSCOOKIE or HTTP date */
+ * either as an ::NSCOOKIE or ::HTTP date */
-char *apreq_expires(apr_pool_t *p, const char *time_str, const int type);
+typedef enum {HTTP, NSCOOKIE} apreq_expires_t;
+APREQ_DECLARE(char *) apreq_expires(apr_pool_t *p, const char *time_str,
+ const apreq_expires_t type);
/* file sizes (KMG) to bytes */
apr_int64_t apreq_atoi64(const char *s);
1.5 +35 -17 httpd-apreq-2/src/apreq.c
Index: apreq.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- apreq.c 23 Jan 2003 07:00:41 -0000 1.4
+++ apreq.c 24 Jan 2003 19:15:07 -0000 1.5
@@ -41,13 +41,14 @@
const apr_array_header_t *arr)
{
apreq_value_t *a = *(apreq_value_t **)(arr->elts);
- apreq_value_t *v = apreq_char_to_value( apreq_join(p, ", ", arr, 0) );
+ apreq_value_t *v = apreq_char_to_value( apreq_join(p, ", ", arr, AS_IS)
);
if (arr->nelts > 0)
v->name = a->name;
return v;
}
-char *apreq_expires(apr_pool_t *p, const char *time_str, const int type)
+APREQ_DECLARE(char *) apreq_expires(apr_pool_t *p, const char *time_str,
+ const apreq_expires_t type)
{
apr_time_t when;
apr_time_exp_t tms;
@@ -74,7 +75,7 @@
/* used for specifying file & byte sizes */
-apr_int64_t apreq_atoi64(const char *s) {
+APREQ_DECLARE(apr_int64_t) apreq_atoi64(const char *s) {
apr_int64_t n = 0;
char *p;
if (s == NULL)
@@ -99,7 +100,7 @@
/* converts date offsets (e.g. "+3M") to seconds */
-long apreq_atol(const char *s)
+APREQ_DECLARE(long) apreq_atol(const char *s)
{
apr_int64_t n = 0;
char *p;
@@ -183,7 +184,7 @@
}
static const char c2x_table[] = "0123456789abcdef";
-static char x2c(const char *what)
+static APR_INLINE char x2c(const char *what)
{
register char digit;
@@ -203,11 +204,12 @@
return (digit);
}
-apr_ssize_t apreq_unescape(char *d, const char *s, const apr_size_t slen)
+apr_ssize_t apreq_decode(char *d, const char *s, const apr_size_t slen)
{
register int badesc = 0;
char *start = d;
const char *end = s + slen;
+
if (s == NULL || d == NULL)
return -1;
@@ -268,7 +270,7 @@
}
-apr_size_t apreq_escape(char *dest, const char *src,
+apr_size_t apreq_encode(char *dest, const char *src,
const apr_size_t slen)
{
char *d = dest;
@@ -342,7 +344,7 @@
APREQ_DECLARE(const char *) apreq_join(apr_pool_t *p,
const char *sep,
const apr_array_header_t *arr,
- int mode)
+ apreq_join_t mode)
{
apr_ssize_t len, slen;
apreq_value_t *rv;
@@ -362,12 +364,14 @@
/* Allocated the required space */
switch (mode) {
- case APREQ_JOIN_ESCAPE:
+ case ENCODE:
len += 2 * len;
break;
- case APREQ_JOIN_QUOTE:
+ case QUOTE:
len = 2 * (len + n);
break;
+ default:
+ /* nothing special required, just here to keep noisy compilers happy
*/
}
rv = apr_palloc(p, len + sizeof *rv);
@@ -385,18 +389,18 @@
switch (mode) {
- case APREQ_JOIN_ESCAPE:
- d += apreq_escape(d, a[0]->data, a[0]->size);
+ case ENCODE:
+ d += apreq_encode(d, a[0]->data, a[0]->size);
for (j = 1; j < n; ++j) {
memcpy(d, sep, slen);
d += slen;
- d += apreq_escape(d, a[j]->data, a[j]->size);
+ d += apreq_encode(d, a[j]->data, a[j]->size);
}
break;
- case APREQ_JOIN_UNESCAPE:
- len = apreq_unescape(d, a[0]->data, a[0]->size);
+ case DECODE:
+ len = apreq_decode(d, a[0]->data, a[0]->size);
if (len < 0) {
rv->status = APR_BADCH;
@@ -409,7 +413,7 @@
memcpy(d, sep, slen);
d += slen;
- len = apreq_unescape(d, a[j]->data, a[j]->size);
+ len = apreq_decode(d, a[j]->data, a[j]->size);
if (len < 0) {
rv->status = APR_BADCH;
@@ -421,7 +425,7 @@
break;
- case APREQ_JOIN_QUOTE:
+ case QUOTE:
d += apreq_quote(d, a[0]->data, a[0]->size);
for (j = 1; j < n; ++j) {
@@ -448,5 +452,19 @@
*d = 0;
rv->size = d - rv->data;
+ return rv->data;
+}
+
+APREQ_DECLARE(char *) apreq_escape(apr_pool_t *p,
+ const char *src, const apr_size_t slen)
+{
+ apreq_value_t *rv;
+ if (src == NULL || slen == 0)
+ return NULL;
+
+ rv = apr_palloc(p, 3 * slen + sizeof *rv);
+ rv->name = NULL;
+ rv->status = APR_SUCCESS;
+ rv->size = apreq_encode(rv->data, src, slen);
return rv->data;
}
1.2 +16 -8 httpd-apreq-2/src/apreq_params.h
Index: apreq_params.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_params.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- apreq_params.h 24 Jan 2003 04:29:09 -0000 1.1
+++ apreq_params.h 24 Jan 2003 19:15:07 -0000 1.2
@@ -81,6 +81,12 @@
apreq_value_t v;
} apreq_param_t;
+#define apreq_value_to_param(ptr) apreq_attr_to_type(apreq_param_t, \
+ v, ptr)
+#define apreq_param_name(p) ((p)->v.name)
+#define apreq_param_value(p) ((p)->v.data)
+
+
/* XXX this might be better as an ADT */
typedef struct apreq_request_t {
@@ -109,11 +115,11 @@
* @remark Also parses the request as necessary.
*/
-APREQ_DECLARE(const char *) apreq_param(apreq_request_t *req,
- const char *key);
+APREQ_DECLARE(const apreq_param_t *) apreq_param(const apreq_request_t *req,
+ const char *name);
APREQ_DECLARE(const char *) apreq_arg(const apreq_request_t *req,
- const char *key);
+ const char *name);
#define apreq_arg(r,k) apreq_table_get((req)->arg, k)
@@ -135,9 +141,9 @@
*/
APREQ_DECLARE(apr_array_header_t *) apreq_params(
- const apreq_request_t *req,
apr_pool_t *p,
- const char *key);
+ const apreq_request_t *req,
+ const char *name);
/**
* Returns a ", " -separated string containing all parameters
@@ -157,15 +163,17 @@
*/
APREQ_DECLARE(apr_array_header_t *) apreq_keys(apreq_request_t *req);
-APREQ_DECLARE(apr_status_t) apreq_param_split(apreq_table_t *t,
- apr_pool_t *pool,
+APREQ_DECLARE(apr_status_t) apreq_param_split(apr_pool_t *pool,
+ apreq_table_t *t,
const char *data,
- apr_size_t dlen);
+ const apr_size_t dlen);
APREQ_DECLARE(apreq_param_t *) apreq_param_decode(apr_pool_t *pool,
const char *word,
const apr_size_t nlen,
const apr_size_t vlen);
+APREQ_DECLARE(char *) apreq_param_encode(apr_pool_t *pool,
+ const apreq_param_t *param);
#ifdef __cplusplus
1.2 +44 -14 httpd-apreq-2/src/apreq_params.c
Index: apreq_params.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_params.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- apreq_params.c 24 Jan 2003 04:29:09 -0000 1.1
+++ apreq_params.c 24 Jan 2003 19:15:07 -0000 1.2
@@ -60,6 +60,8 @@
#include "apreq_env.h"
#define p2v(param) ( (param) ? &(param)->v : NULL )
+#define UPGRADE(s) apreq_value_to_param(apreq_char_to_value(s))
+
APREQ_DECLARE(apreq_request_t *) apreq_request(void *ctx)
{
@@ -96,13 +98,13 @@
query_string = apreq_env_args(ctx);
req->status = (query_string == NULL) ? APR_SUCCESS :
- apreq_param_split(req->args, p, query_string, strlen(query_string));
+ apreq_param_split(p, req->args, query_string, strlen(query_string));
return req;
}
-apr_status_t apreq_parse(apreq_request_t *req)
+APREQ_DECLARE(apr_status_t) apreq_parse(apreq_request_t *req)
{
if (req->body == NULL)
if (req->status == APR_SUCCESS)
@@ -117,23 +119,29 @@
return req->status;
}
-const char *apreq_param(apreq_request_t *req, const char *key)
+
+APREQ_DECLARE(const apreq_param_t *)apreq_param(const apreq_request_t *req,
+ const char *name)
{
- const char *param = apreq_table_get(req->args, key);
- return param ? param : apreq_table_get(req->body, key);
+ const apreq_param_t *param = UPGRADE(apreq_table_get(req->args, name));
+ return param ? param : UPGRADE(apreq_table_get(req->body, name));
}
-apr_array_header_t *apreq_params(const apreq_request_t *req,
- apr_pool_t *pool,
- const char *key)
+
+APREQ_DECLARE(apr_array_header_t *) apreq_params(apr_pool_t *pool,
+ const apreq_request_t *req,
+ const char *name)
{
- apr_array_header_t *arr = apreq_table_values(req->args, pool, key);
- apr_array_cat(arr, apreq_table_values(req->body, pool, key));
+ apr_array_header_t *arr = apreq_table_values(pool, req->args, name);
+ apr_array_cat(arr, apreq_table_values(pool, req->body, name));
return arr;
}
-apr_status_t apreq_param_split(apreq_table_t *t, apr_pool_t *pool,
- const char *data, apr_size_t dlen)
+
+APREQ_DECLARE(apr_status_t) apreq_param_split(apr_pool_t *pool,
+ apreq_table_t *t,
+ const char *data,
+ apr_size_t dlen)
{
const char *start = data, *end = data + dlen;
apr_size_t nlen = 0;
@@ -196,7 +204,7 @@
param->v.status = APR_SUCCESS;
param->v.name = NULL;
- size = apreq_unescape(param->v.data, word + nlen + 1, vlen);
+ size = apreq_decode(param->v.data, word + nlen + 1, vlen);
if (size < 0) {
param->v.size = 0;
@@ -207,8 +215,30 @@
param->v.size = size;
param->v.name = param->v.data + size + 1;
- if (apreq_unescape(param->v.data + size + 1, word, nlen) < 0)
+ if (apreq_decode(param->v.data + size + 1, word, nlen) < 0)
param->v.status = APR_BADCH;
return param;
+}
+
+
+APREQ_DECLARE(char *) apreq_param_encode(apr_pool_t *pool,
+ const apreq_param_t *param)
+{
+ apreq_value_t *v;
+ apr_size_t nlen;
+
+ if (param->v.name == NULL || param->v.status != APR_SUCCESS)
+ return NULL;
+
+ nlen = strlen(param->v.name);
+
+ v = apr_palloc(pool, 3 * (nlen + param->v.size) + 2 + sizeof *v);
+ v->name = param->v.name;
+ v->status = APR_SUCCESS;
+ v->size = apreq_encode(v->data, param->v.name, nlen);
+ v->data[v->size++] = '=';
+ v->size += apreq_encode(v->data + v->size, param->v.data, param->v.size);
+
+ return v->data;
}