-rw-r--r-- | src/util.cc | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/util.cc b/src/util.cc new file mode 100644 index 0000000..2e2d305 --- a/dev/null +++ b/src/util.cc | |||
@@ -0,0 +1,53 @@ | |||
1 | #include "kingate/util.h" | ||
2 | #include "kingate/exception.h" | ||
3 | |||
4 | namespace kingate { | ||
5 | |||
6 | static const char *safeChars = | ||
7 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | ||
8 | "abcdefghijklmnopqrstuvwxyz" | ||
9 | "0123456789" | ||
10 | "_-" ; | ||
11 | |||
12 | string url_escape(const string& str) { | ||
13 | string rv = str; | ||
14 | string::size_type screwed = 0; | ||
15 | for(;;) { | ||
16 | screwed = rv.find_first_not_of(safeChars,screwed); | ||
17 | if(screwed == string::npos) | ||
18 | break; | ||
19 | while(screwed<rv.length() && !strchr(safeChars,rv.at(screwed))) { | ||
20 | char danger = rv.at(screwed); | ||
21 | if(danger==' ') { | ||
22 | rv.replace(screwed++,1,1,'+'); | ||
23 | }else{ | ||
24 | static char tmp[4] = {'%',0,0,0}; | ||
25 | snprintf(&tmp[1],3,"%02X",0xFF&(int)danger); | ||
26 | rv.replace(screwed,1,tmp,3); | ||
27 | screwed+=3; | ||
28 | } | ||
29 | } | ||
30 | } | ||
31 | return rv; | ||
32 | } | ||
33 | string url_unescape(const string& str) { | ||
34 | string rv = str; | ||
35 | string::size_type unscrewed = 0; | ||
36 | for(;;) { | ||
37 | unscrewed = rv.find_first_of("%+",unscrewed); | ||
38 | if(unscrewed == string::npos) | ||
39 | break; | ||
40 | if(rv.at(unscrewed)=='+') { | ||
41 | rv.replace(unscrewed++,1,1,' '); | ||
42 | }else{ | ||
43 | if((rv.length()-unscrewed)<3) | ||
44 | throw exception(CODEPOINT,"incorrectly escaped string"); | ||
45 | // XXX: ensure it's hex? | ||
46 | int danger = strtol(rv.substr(unscrewed+1,2).c_str(),NULL,16); | ||
47 | rv.replace(unscrewed,3,1,danger); | ||
48 | unscrewed++; | ||
49 | } | ||
50 | } | ||
51 | return rv; | ||
52 | } | ||
53 | } | ||