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