[REBOL] Re: x-www-form-urlencoded (bug in bitset! or find ?)
From: alex:pini:mclink:it at: 3-Sep-2000 18:09
>- Open Your Mind -<
Quoting from Eric's message (02-Sep-00 05:23:14).
K> Actually, maybe it's better to do this with PARSE:
My thinking exactly. :-)
K> url-encode: func [
K> {URL-encode a string}
K> data "String to encode"
K> /local new-data normal-char c
K> ] compose [
K> new-data: make string! ""
K> normal-char: (charset [
K> #"A" - #"Z" #"a" - #"z"
K> #"@" #"." #"*" #"-" #"_"
K> #"0" - #"9"
K> ])
K> if not string? data [return new-data]
K> parse data [ some [
K> copy c normal-char
K> (append new-data c) |
K> copy c skip
K> (append new-data reduce ["%" skip tail (to-hex 0 + first c) -2])
K> ] ]
K> new-data
K> ]
I've modified your version a little, striving to obtain RFC-compliance (which is impossible,
since they contradict one another and sometimes themselves)-:
url-encode: func [
"URL-encodes a string."
value [string!] "The string to encode"
/local url-encoded-string normal-char char
] compose [
url-encoded-string: make string! ""
normal-char: (charset [ #"A" - #"Z" #"a" - #"z" #"0" - #"9" "$-_.!*'()," ])
parse/all value [
any [
copy char normal-char (append url-encoded-string char) |
copy char " " (append url-encoded-string "+") |
copy char newline (append url-encoded-string "%0D%0A") |
copy char skip (append url-encoded-string reduce ["%" skip tail (to-hex 0 + first
char) -2])
]
]
url-encoded-string
]
The differences:
datatype checking (I need to be notified when I do something wrong :-);
all charset's special characters are now in a string for clarity;
the special characters are now the ones specified in RFC 1738, minus the plus (huh? :-);
white space (" ") is now transformed into a plus ("+"), as per HTML 4.01 specs, which
de-facto obsolete RFC 1866;
line break is now transformed into the pair "%0D%0A", as per HTML 4.01 specs;
the "some" word is now "any" to deal with empty strings (even if results don't change:
pedantic now, no headaches later);
layout and some names changed to meet REBOL standards and to suit my tastes :-)
You can try it using for example the following 2 lines.
s: copy "" for c #"^(00)" #"^(fe)" 1 [append s c] append s #"^(ff)"
probe url-encode s
Two doubts still remain.
First, I'm not sure if I'm doing the right thing by changing the special characters in
the charset: some of my browsers agree with the previous version, so maybe there's a
de-facto standard *I* am not respecting. If so, please point me in the right direction.
:-)
Second, I guess the newline check isn't sufficient for everyone. Then again, newline
is right for the platform the script is running on... and if you use this function you
probably know how to (easily) go around possible obstacles.
Alessandro Pini ([alex--pini--mclink--it])
Did you accidentally inject yourself with some kind of... psychotropic agent?
(Kim)