First pass at importing some apreq functions. Not yet had time to wirte
a test! Rushing out of door, so just a quick mail :-)
More integration with apr_uri structure is planned, but not yet had time
to finish that bit :-)
-- Index: include/apr_uri.h
===================================================================
--- include/apr_uri.h (revision 427948)
+++ include/apr_uri.h (working copy)
@@ -170,6 +170,31 @@
const char *hostinfo,
apr_uri_t *uptr);
+/**
+ * @fn apr_size_t apr_uri_query_string_encode(char *dest, const char *src,
+ const apr_size_t slen)
+ * @brief URI encode a query string
+ * @param dest the destination pointer
+ * @param src the source pointer
+ * @param slen length of source string
+ */
+APU_DECLARE(apr_size_t) apr_uri_query_string_encode(char *, const char *,
+ const apr_size_t);
+
+/**
+ * @fn apr_status_t apr_uri_query_string_decode(char *d, apr_size_t *dlen,
+ const char *s,
+ apr_size_t slen)
+ * @brief URI Decode a query string
+ * @param d destination pointer
+ * @param dlen length of created string
+ * @param s source pointer
+ * @param slen length of source string
+ */
+APU_DECLARE(apr_status_t) apr_uri_query_string_decode(char *, apr_size_t *,
+ const char *,
+ apr_size_t);
+
/** @} */
#ifdef __cplusplus
}
Index: build.conf
===================================================================
--- build.conf (revision 427948)
+++ build.conf (working copy)
@@ -15,7 +15,7 @@
ldap/*.c
misc/*.c
memcache/*.c
- uri/apr_uri.c
+ uri/*.c
xml/*.c
strmatch/*.c
xlate/*.c
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
* applicable.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* apr_uri_coding.c: URI related utility things
*
*/
#include "apr_strings.h"
#include "apr_lib.h"
#include "apu.h"
static const char c2x_table[] = "0123456789ABCDEF";
static APR_INLINE unsigned char hex2_to_char(const char *what)
{
register unsigned char digit;
#if !APR_CHARSET_EBCDIC
digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0]
- '0'));
digit *= 16;
digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10 : (what[1]
- '0'));
#else /*APR_CHARSET_EBCDIC*/
char xstr[5];
xstr[0]='0';
xstr[1]='x';
xstr[2]=what[0];
xstr[3]=what[1];
xstr[4]='\0';
digit = apr_xlate_conv_byte(ap_hdrs_from_ascii, 0xFF & strtol(xstr,
NULL, 16));
#endif /*APR_CHARSET_EBCDIC*/
return (digit);
}
static APR_INLINE apr_uint16_t hex4_to_bmp(const char *what)
{
register apr_uint16_t digit = 0;
#if !APR_CHARSET_EBCDIC
digit = (what[0] >= 'A' ? ((what[0] & 0xDF)-'A') + 10 : (what[0]-'0'));
digit *= 16;
digit += (what[1] >= 'A' ? ((what[1] & 0xDF)-'A') + 10 : (what[1]-'0'));
digit *= 16;
digit += (what[2] >= 'A' ? ((what[2] & 0xDF)-'A') + 10 : (what[2]-'0'));
digit *= 16;
digit += (what[3] >= 'A' ? ((what[3] & 0xDF)-'A') + 10 : (what[3]-'0'));
#else /*APR_CHARSET_EBCDIC*/
char xstr[7];
xstr[0]='0';
xstr[1]='x';
xstr[2]=what[0];
xstr[3]=what[1];
xstr[4]=what[2];
xstr[5]=what[3];
xstr[6]='\0';
digit = apr_xlate_conv_byte(ap_hdrs_from_ascii, 0xFFFF &
strtol(xstr, NULL, 16));
#endif /*APR_CHARSET_EBCDIC*/
return (digit);
}
static apr_status_t url_decode(char *dest, apr_size_t *dlen,
const char *src, apr_size_t *slen)
{
register const char *s = src;
unsigned char *start = (unsigned char *)dest;
register unsigned char *d = (unsigned char *)dest;
const char *end = src + *slen;
for (; s < end; ++d, ++s) {
switch (*s) {
case '+':
*d = ' ';
break;
case '%':
if (s + 2 < end && apr_isxdigit(s[1]) && apr_isxdigit(s[2]))
{
*d = hex2_to_char(s + 1);
s += 2;
}
else if (s + 5 < end && (s[1] == 'u' || s[1] == 'U') &&
apr_isxdigit(s[2]) && apr_isxdigit(s[3]) &&
apr_isxdigit(s[4]) && apr_isxdigit(s[5]))
{
apr_uint16_t c = hex4_to_bmp(s+2);
if (c < 0x80) {
*d = c;
}
else if (c < 0x800) {
*d++ = 0xC0 | (c >> 6);
*d = 0x80 | (c & 0x3F);
}
else {
*d++ = 0xE0 | (c >> 12);
*d++ = 0x80 | ((c >> 6) & 0x3F);
*d = 0x80 | (c & 0x3F);
}
s += 5;
}
else {
*dlen = d - start;
*slen = s - src;
if (s + 5 < end
|| (s + 2 < end && !apr_isxdigit(s[2]))
|| (s + 1 < end && !apr_isxdigit(s[1])
&& s[1] != 'u' && s[1] != 'U'))
{
*d = 0;
return 1;
}
memmove(d, s, end - s);
d[end - s] = 0;
return 2;
}
break;
default:
if (*s > 0) {
*d = *s;
}
else {
*d = 0;
*dlen = d - start;
*slen = s - src;
return 1;
}
}
}
*d = 0;
*dlen = d - start;
*slen = s - src;
return APR_SUCCESS;
}
APU_DECLARE(apr_size_t) apr_uri_query_string_encode(char *dest, const
char *src,
const apr_size_t slen)
{
char *d = dest;
const unsigned char *s = (const unsigned char *)src;
unsigned char c;
for ( ; s < (const unsigned char *)src + slen; ++s) {
c = *s;
if ( c < 0x80 && (apr_isalnum(c)
|| c == '-' || c == '.'
|| c == '_' || c == '~') )
*d++ = c;
else if ( c == ' ' )
*d++ = '+';
else {
#if APR_CHARSET_EBCDIC
c = apr_xlate_conv_byte(ap_hdrs_to_ascii, (unsigned char)c);
#endif
*d++ = '%';
*d++ = c2x_table[c >> 4];
*d++ = c2x_table[c & 0xf];
}
}
*d = 0;
return d - dest;
}
APU_DECLARE(apr_status_t) apr_uri_query_string_decode(char *d,
apr_size_t *dlen,
const char *s,
apr_size_t slen)
{
apr_size_t len = 0;
const char *end = s + slen;
if (s == (const char *)d) { /* optimize for src = dest case */
for ( ; d < end; ++d) {
if (*d == '%' || *d == '+')
break;
else if (*d == 0) {
*dlen = (const char *)d - s;
return -1;
}
}
len = (const char *)d - s;
s = (const char *)d;
slen -= len;
}
return url_decode(d, dlen, s, &slen);
}
david
http://feathercast.org/