ATLAS Offline Software
Loading...
Searching...
No Matches
urldecode.h
Go to the documentation of this file.
1/* urldecode - decode application/x-www-form-urlencoded data
2
3 Copyright (C) 2009 ePoint Systems Ltd.
4 Author: Rooslan S. Khayrov
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <unistd.h>
21#include <strings.h>
22#include <sstream>
23#include <string>
24
25namespace urldecode
26{
27
28static int hexdigit(char c)
29{
30 if (c >= '0' && c <= '9')
31 return c - '0';
32 if (c >= 'A' && c <= 'F')
33 return 10 + c - 'A';
34 if (c >= 'a' && c <= 'f')
35 return 10 + c - 'a';
36 return -1;
37}
38
40
41typedef struct decoder_state_s
42{
43 int state;
44 char sym;
46
47int is_unreserved(char c)
48{
49 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
50 (c >= '0' && c <= '9') || index("-_.~!*'();:@&=+$,/?%#[]", c);
51}
52
59ssize_t urldecode(decoder_state *state, char *data, size_t size)
60{
61 size_t inpos = 0, outpos = 0;
62 int d1, d2;
63 while (inpos < size)
64 {
65 char in = data[inpos++];
66 switch (in)
67 {
68 case '%':
69 switch (state->state)
70 {
71 case ST_SYM:
72 state->state = ST_PERCENT;
73 break;
74 default:
75 return -1;
76 }
77 break;
78 case '+':
79 switch (state->state)
80 {
81 case ST_SYM:
82 data[outpos++] = ' ';
83 break;
84 default:
85 return -1;
86 }
87 break;
88 default:
89 switch (state->state)
90 {
92 d1 = hexdigit(state->sym), d2 = hexdigit(in);
93 if (d1 >= 0 && d2 >= 0)
94 {
95 data[outpos++] = (d1 << 4) | d2;
96 }
97 else
98 {
99 return -1;
100 }
101 state->state = ST_SYM;
102 break;
103 case ST_PERCENT:
104 state->sym = in;
105 state->state = ST_PERCENT_AND_SYM;
106 break;
107 case ST_SYM:
108 if (is_unreserved(in))
109 {
110 data[outpos++] = in;
111 }
112 else
113 {
114 return -1;
115 }
116 break;
117 }
118 }
119 }
120 return outpos;
121}
122
123
124std::pair<std::string,int> urldecode(decoder_state *state, const std::string& data, size_t size)
125{
126 size_t inpos = 0;
127 int outpos = 0;
128 int d1, d2;
129 std::stringstream output;
130 while (inpos < size)
131 {
132 char in = data[inpos++];
133 switch (in)
134 {
135 case '%':
136 switch (state->state)
137 {
138 case ST_SYM:
139 state->state = ST_PERCENT;
140 break;
141 default:
142 outpos=-1;
143 }
144 break;
145 case '+':
146 switch (state->state)
147 {
148 case ST_SYM:
149 //data[outpos++] = ' ';
150 output << ' ';
151 break;
152 default:
153 outpos=-1;
154 }
155 break;
156 default:
157 switch (state->state)
158 {
160 d1 = hexdigit(state->sym), d2 = hexdigit(in);
161 if (d1 >= 0 && d2 >= 0)
162 {
163 //data[outpos++] = (d1 << 4) | d2;
164 char temp = (d1 << 4) | d2;
165 output << temp;
166 }
167 else
168 {
169 outpos=-1;
170 }
171 state->state = ST_SYM;
172 break;
173 case ST_PERCENT:
174 state->sym = in;
175 state->state = ST_PERCENT_AND_SYM;
176 break;
177 case ST_SYM:
178 if (is_unreserved(in))
179 {
180 //data[outpos++] = in;
181 output << in;
182 }
183 else
184 {
185 outpos=-1;
186 }
187 break;
188 }
189 }
190 }
191 return std::make_pair(output.str(),outpos);
192}
193
194} // end namespace urldecode
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
Definition index.py:1
@ ST_PERCENT_AND_SYM
Definition urldecode.h:39
int is_unreserved(char c)
Definition urldecode.h:47
struct urldecode::decoder_state_s decoder_state
static int hexdigit(char c)
Definition urldecode.h:28