char * chxj_url_decode(apr_pool_t *pool, const char *src) { char *dst; int len; int ii; int jj; if (!src) return apr_pstrdup(pool, "\0"); len = strlen(src); dst = apr_palloc(pool, len+1); memset(dst, 0, len+1); for (jj=0,ii=0; src[ii] != '\0' && ii < len; ii++) { if (src[ii] == '%') { if (ii + 2 <= len && IS_HEXCHAR(src[ii+1]) && IS_HEXCHAR(src[ii+2])) { dst[jj++] = s_hex_value(src[ii+1]) * 16 + s_hex_value(src[ii+2]); ii+=2; } } else if (src[ii] == '+') { dst[jj++] = ' '; } else { dst[jj++] = src[ii]; } } return dst; }
/* * [RFC2554] * DIGIT = %x30-39 ;; Digits 0-9 * HEXDIGIT = %x41-46 / DIGIT ;; hexidecimal digit (uppercase) * hexchar = "+" HEXDIGIT HEXDIGIT */ static int XParse_hexchar(const char *head, const char *tail, const char **nextp, XBuffer *xbuf) { if ((head + 2 < tail) && ('+' == *head) && IS_HEXCHAR(*(head + 1)) && IS_HEXCHAR(*(head + 2))) { XBuffer_appendChar(xbuf, CHAR2HEX(*(head + 1)) * 0x10 + CHAR2HEX(*(head + 2))); *nextp = head + 3; return 3; } else { *nextp = head; return 0; } // end if } // end function : XParse_hexchar