OSDN Git Service

* version up.
[modchxj/mod_chxj.git] / src / chxj_url_encode.c
1 /*
2  * Copyright (C) 2005-2009 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(apr_pool_t *pool, const char *src)
41 {
42   char *dst;
43   register char *sp = (char *)src;
44   int len;
45   register int pos;
46
47   if (! src) return apr_pstrdup(pool, "\0");
48
49   len = strlen(src) * 3 + 1;
50   dst = apr_palloc(pool, len);
51   memset(dst, 0, len);
52   pos = 0;
53
54   while(*sp) {
55     if (IS_ALPHA_UPPER(*sp) || IS_ALPHA_LOWER(*sp) || IS_DIGIT(*sp)) {
56       dst[pos++] = *sp++;
57       continue;
58     }
59     if (*sp == ' ') {
60       dst[pos++] = '+';
61       sp++;
62       continue;
63     }
64
65     dst[pos++] = '%';
66     dst[pos++] = TO_HEXSTRING((*sp >> 4) & 0x0f);
67     dst[pos++] = TO_HEXSTRING((*sp & 0x0f));
68     sp++;
69   }
70   return dst;
71 }
72
73
74 char *
75 chxj_url_decode(apr_pool_t *pool, const char *src)
76 {
77   char  *dst;
78   int   len; 
79   int   ii;
80   int   jj;
81
82
83   if (!src) return apr_pstrdup(pool, "\0");
84
85   len = strlen(src);
86   dst = apr_palloc(pool, len+1);
87   memset(dst, 0, len+1);
88
89   for (jj=0,ii=0; src[ii] != '\0' && ii < len; ii++) {
90     if (src[ii] == '%') {
91       if (ii + 2 <= len && IS_HEXCHAR(src[ii+1]) && IS_HEXCHAR(src[ii+2])) {       
92         dst[jj++] = s_hex_value(src[ii+1]) * 16 + s_hex_value(src[ii+2]);
93         ii+=2;
94       }
95     }
96     else if (src[ii] == '+') {
97       dst[jj++] = ' ';
98     }
99     else {
100       dst[jj++] = src[ii];
101     }
102   }
103
104   return dst;
105 }
106 /*
107  * vim:ts=2 et
108  */