summaryrefslogtreecommitdiffabout
path: root/src/util.cc
blob: 2e2d3057732874e37ecbe055f56a0b0c30336656 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include "kingate/util.h"
#include "kingate/exception.h"

namespace kingate {

    static const char *safeChars = 
	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	"abcdefghijklmnopqrstuvwxyz"
	"0123456789"
	"_-" ;

    string url_escape(const string& str) {
	string rv = str;
	string::size_type screwed = 0;
	for(;;) {
	    screwed = rv.find_first_not_of(safeChars,screwed);
	    if(screwed == string::npos)
		break;
	    while(screwed<rv.length() && !strchr(safeChars,rv.at(screwed))) {
		char danger = rv.at(screwed);
		if(danger==' ') {
		    rv.replace(screwed++,1,1,'+');
		}else{
		    static char tmp[4] = {'%',0,0,0};
		    snprintf(&tmp[1],3,"%02X",0xFF&(int)danger);
		    rv.replace(screwed,1,tmp,3);
		    screwed+=3;
		}
	    }
	}
	return rv;
    }
    string url_unescape(const string& str) {
	string rv = str;
	string::size_type unscrewed = 0;
	for(;;) {
	    unscrewed = rv.find_first_of("%+",unscrewed);
	    if(unscrewed == string::npos)
		break;
	    if(rv.at(unscrewed)=='+') {
		rv.replace(unscrewed++,1,1,' ');
	    }else{
		if((rv.length()-unscrewed)<3)
		    throw exception(CODEPOINT,"incorrectly escaped string");
		// XXX: ensure it's hex?
		int danger = strtol(rv.substr(unscrewed+1,2).c_str(),NULL,16);
		rv.replace(unscrewed,3,1,danger);
		unscrewed++;
	    }
	}
	return rv;
    }
}