<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf8">
<title>/usr/web/sources/contrib/maht/url_encode.c - Plan 9 from Bell Labs</title>
<!-- THIS FILE IS AUTOMATICALLY GENERATED. -->
<!-- EDIT sources.tr INSTEAD. -->
</meta>
</head>
<body>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 10pt"><a href="/plan9/">Plan 9 from Bell Labs</a>&rsquo;s /usr/web/sources/contrib/maht/url_encode.c</span></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center><font size=-1>
Copyright © 2009 Alcatel-Lucent.<br />
Distributed under the
<a href="/plan9/license.html">Lucent Public License version 1.02</a>.
<br />
<a href="/plan9/download.html">Download the Plan 9 distribution.</a>
</font>
</center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<table width="100%" cellspacing=0 border=0><tr><td align="center">
<table cellspacing=0 cellpadding=5 bgcolor="#eeeeff"><tr><td align="left">
<pre>
<!-- END HEADER -->
#include &lt;u.h&gt;
#include &lt;libc.h&gt;
#include &lt;ctype.h&gt;

int url_encode(Fmt *fmt) {
	int cnt;
	uchar c, e;
	char *str_start;
	char *str_index;

	static int url_trans_flag[] = { [32] 0, [33] 0, [34] 0, [35] 0, [36] 0, [37] 0, [38] 0, [39] 0, [40] 0, [41] 0, [42] 0, [43] 0, [44] 0, [45] '-', [46] '.', [47] 0, [48] '0', [49] '1', [50] '2', [51] '3', [52] '4', [53] '5', [54] '6', [55] '7', [56] '8', [57] '9', [58] 0, [59] 0, [60] 0, [61] 0, [62] 0, [63] 0, [64] 0, [65] 'A', [66] 'B', [67] 'C', [68] 'D', [69] 'E', [70] 'F', [71] 'G', [72] 'H', [73] 'I', [74] 'J', [75] 'K', [76] 'L', [77] 'M', [78] 'N', [79] 'O', [80] 'P', [81] 'Q', [82] 'R', [83] 'S', [84] 'T', [85] 'U', [86] 'V', [87] 'W', [88] 'X', [89] 'Y', [90] 'Z', [91] 0, [92] 0, [93] 0, [94] 0, [95] '_', [96] 0, [97] 'a', [98] 'b', [99] 'c', [100] 'd', [101] 'e', [102] 'f', [103] 'g', [104] 'h', [105] 'i', [106] 'j', [107] 'k', [108] 'l', [109] 'm', [110] 'n', [111] 'o', [112] 'p', [113] 'q', [114] 'r', [115] 's', [116] 't', [117] 'u', [118] 'v', [119] 'w', [120] 'x', [121] 'y', [122] 'z', [123] 0, [124] 0, [125] 0, [126] 0, [127] 0 };

	str_start = str_index= smprint("%s", va_arg(fmt-&gt;args, char *));
	if (fmt-&gt;flags &amp; FmtSign)
		url_trans_flag[32] = '+';
	else
		url_trans_flag[32] = 0;

	cnt = 0;
	while(c = *(str_index++)) {
		if (c &gt; 127 || c &lt; 32) {
			cnt += fmtprint(fmt, "%%%02x", c);
			continue;
		}

		e = url_trans_flag[c];
		if(e) 
			cnt += fmtprint(fmt, "%c", e);
		else
			cnt += fmtprint(fmt, "%%%02x", c);
	}
	free(str_start);
	return cnt;
}

int 
url_decode(Fmt *fmt) {
	char *str_arg;
	char *str_start;
	char * token;
	int token_index;
	int str_length;
	int ante_token_length;
	int c, cnt, t;
	Rune r;


	str_start = str_arg = smprint("%s", va_arg(fmt-&gt;args, char *));
	for (token = str_arg ; *token; token++) if (*(token) == '+') *token = ' ';

	cnt = 0;
	while(token =  strchr(str_arg, '%')) {	
		str_length = strlen(str_arg);
		token_index = str_length - strlen(token);
		ante_token_length = str_length - token_index - 1;

		if (token_index) { 
			str_arg[token_index] = 0;
			cnt += fmtprint(fmt, "%s",	str_arg);
		}

		if (ante_token_length &lt; 1) {
			str_arg = token +1;
			continue;
		}

		if(token[1] == '%') {
			cnt += fmtprint(fmt, "%%");
			str_arg = &amp;token[2];
			continue;
		}
		
		if ((ante_token_length &gt; 1) &amp;&amp; isxdigit(token[1]) &amp;&amp; isxdigit(token[2]) ) {
			t = token[3];
			token[3] = 0;
			r = strtol(&amp;token[1], nil, 16);
			cnt += fmtprint(fmt, "%C",r);
			token[3] = t;
			str_arg = &amp;token[3];
			continue;
		}
		
		// if we get here the string is malformed, I'll silently drop it 
		str_arg++;
	}
	if(*str_arg)
		cnt += fmtprint(fmt, "%s",	str_arg);
	free(str_start);
	return cnt;

}


int 
url_encoding(Fmt *fmt) {	
	if(fmt-&gt;flags &amp; FmtLeft) 
		return url_decode(fmt);
	else 
		return url_encode(fmt);
}






/*

here's an example

8c url_encode.c &amp;&amp; 8l url_encode.8 &amp;&amp; mv 8.out url_encode &amp;&amp; ./url_encode

output is :

fancy : caf€ bl€nc
+enc : caf%e9+bl%e1nc
%20 enc : caf%e9%20bl%e1nc
plain : café blánc
oh_no : %c3%b3h%20n%c3%b3
óh nó

*/


void
main (void) {
	char *fancy_string = "cafe blanc";
	char *prev_estring = "caf%E9%20bl%E1nc";
	char *plus_enc_string;
	char *p20_enc_string;
	char *plain_string;

	fancy_string[3] = 0xE9;
	fancy_string[7] = 0xE1;
	
	fmtinstall('R', url_encoding);

	plus_enc_string = smprint("%+R", fancy_string);
	p20_enc_string = smprint("%R", fancy_string);
	plain_string = smprint("%-R", prev_estring);

	print("fancy : %s\n+enc : %s\n%%20 enc : %s\nplain : %s\n", fancy_string, plus_enc_string, p20_enc_string, plain_string);


	print("oh_no : %R\n%-R\n", "óh nó", "%c3%b3h%20n%c3%b3");
	
	
	exits(0);
}
<!-- BEGIN TAIL -->
</pre>
</td></tr></table>
</td></tr></table>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 10pt"></span></p>
<p style="margin-top: 0; margin-bottom: 0.50in"></p>
<p style="margin-top: 0; margin-bottom: 0.33in"></p>
<center><table border="0"><tr>
<td valign="middle"><a href="http://www.alcatel-lucent.com/"><img border="0" src="/plan9/img/logo_ft.gif" alt="Bell Labs" />
</a></td>
<td valign="middle"><a href="http://www.opensource.org"><img border="0" alt="OSI certified" src="/plan9/img/osi-certified-60x50.gif" />
</a></td>
<td><img style="padding-right: 45px;" alt="Powered by Plan 9" src="/plan9/img/power36.gif" />
</td>
</tr></table></center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center>
<span style="font-size: 10pt">(<a href="/plan9/">Return to Plan 9 Home Page</a>)</span>
</center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center><font size=-1>
<span style="font-size: 10pt"><a href="http://www.lucent.com/copyright.html">Copyright</a></span>
<span style="font-size: 10pt">© 2009 Alcatel-Lucent.</span>
<span style="font-size: 10pt">All Rights Reserved.</span>
<br />
<span style="font-size: 10pt">Comments to</span>
<span style="font-size: 10pt"><a href="mailto:webmaster@plan9.bell-labs.com">webmaster@plan9.bell-labs.com</a>.</span>
</font></center>
</body>
</html>