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/