OSDN Git Service

* Added test code of the <plaintext> for au XHTML converter.
[modchxj/mod_chxj.git] / src / chxj_url_encode.c
1 /*
2  * Copyright (C) 2005-2008 Atsushi Konno All rights reserved.
3  * Copyright (C) 2005 QSDN,Inc. All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #include "mod_chxj.h"
18 #include "chxj_url_encode.h"
19
20 #define IS_ALPHA_UPPER(X) (((X) >='A') && ((X) <= 'Z'))
21 #define IS_ALPHA_LOWER(X) (((X) >='a') && ((X) <= 'z'))
22 #define IS_DIGIT(X)       (((X) >='0') && ((X) <= '9'))
23 #define TO_HEXSTRING(X)   (((X) < 10) ? (X) + '0' : (X) + ('A' - 10)) 
24 #define IS_HEXCHAR(X)     (                             \
25                              ((X) >= 'A' && (X) <= 'F') \
26                           || ((X) >= 'a' && (X) <= 'f') \
27                           || ((X) >= '0' && (X) <= '9') \
28                           )
29
30 static inline char 
31 s_hex_value(char c)
32 {
33   if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
34   if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
35   if (c >= '0' && c <= '9') return (c - '0' +  0);
36   return 0;
37 }
38
39 char*
40 chxj_url_encode(request_rec* r, const char* src)
41 {
42   char* dst;
43   char* sp = (char*)src;
44   unsigned char tmp;
45
46   dst = apr_palloc(r->pool, 1);
47   dst[0] = 0;
48
49   if (!src) return dst;
50
51
52   while(*sp) {
53
54     if (IS_ALPHA_UPPER(*sp) ||  IS_ALPHA_LOWER(*sp) ||  IS_DIGIT(*sp)) {
55       dst = apr_psprintf(r->pool, "%s%c", dst, *sp);
56       sp++;
57       continue;
58     }
59
60     if (*sp == ' ') {
61       dst = apr_pstrcat(r->pool, dst, "+", NULL);
62       sp++;
63       continue;
64     }
65
66     tmp = (*sp >> 4) & 0x0f;
67     dst = apr_psprintf(r->pool, "%s%%%c", dst, TO_HEXSTRING(tmp));
68     tmp = *sp & 0x0f;
69     dst = apr_psprintf(r->pool, "%s%c", dst,   TO_HEXSTRING(tmp));
70
71     sp++;
72   }
73   
74   return dst;
75 }
76
77 char*
78 chxj_url_decode(request_rec* r, const char* src)
79 {
80   char* dst;
81   int   len; 
82   int   ii;
83   int   jj;
84
85
86   if (!src) return NULL;
87
88   len = strlen(src);
89   dst = apr_palloc(r->pool, len+1);
90   memset(dst, 0, len+1);
91
92   for (jj=0,ii=0; src[ii] != '\0' && ii < len; ii++) {
93     if (src[ii] == '%') {
94       if (ii + 2 <= len && IS_HEXCHAR(src[ii+1]) && IS_HEXCHAR(src[ii+2])) {       
95         dst[jj++] = s_hex_value(src[ii+1]) * 16 + s_hex_value(src[ii+2]);
96         ii+=2;
97       }
98     }
99     else {
100       dst[jj++] = src[ii];
101     }
102   }
103
104   return dst;
105 }
106 /*
107  * vim:ts=2 et
108  */