0196f2b51b1f60bbae69672af776af1ab98dda53
[shibboleth/cpp-xmltooling.git] / xmltooling / util / URLEncoder.cpp
1 /*
2  *  Copyright 2001-2009 Internet2
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * URLEncoder.cpp
19  * 
20  * Interface to a URL-encoding mechanism along with a
21  * default implementation. 
22  */
23
24 #include "internal.h"
25 #include "util/URLEncoder.h"
26
27 using namespace xmltooling;
28 using namespace std;
29
30 static char x2c(char *what)
31 {
32     register char digit;
33
34     digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
35     digit *= 16;
36     digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
37     return(digit);
38 }
39
40 URLEncoder::URLEncoder()
41 {
42 }
43
44 URLEncoder::~URLEncoder()
45 {
46 }
47
48 void URLEncoder::decode(char* s) const
49 {
50     register int x,y;
51
52     for(x=0,y=0;s[y];++x,++y)
53     {
54         if((s[x] = s[y]) == '%' && isxdigit(s[y+1]) && isxdigit(s[y+2]))
55         {
56             s[x] = x2c(&s[y+1]);
57             y+=2;
58         }
59         else if (s[x] == '+')
60         {
61             s[x] = ' ';
62         }
63     }
64     s[x] = '\0';
65 }
66
67 static inline char hexchar(unsigned short s)
68 {
69     return (s<=9) ? ('0' + s) : ('A' + s - 10);
70 }
71
72 string URLEncoder::encode(const char* s) const
73 {
74     string ret;
75     for (; *s; s++) {
76         if (isBad(*s)) {
77             ret+='%';
78             ret+=hexchar((unsigned char)*s >> 4);
79             ret+=hexchar((unsigned char)*s & 0x0F);
80         }
81         else
82             ret+=*s;
83     }
84     return ret;
85 }
86
87 bool URLEncoder::isBad(char ch) const
88 {
89     static char badchars[]="=&/?:\"\\+<>#%{}|^~[],`;@";
90     return (ch<=0x20 || ch>=0x7F || strchr(badchars,ch));
91 }