Skip to content

Instantly share code, notes, and snippets.

@atl
Created November 12, 2009 13:12
Show Gist options
  • Save atl/232884 to your computer and use it in GitHub Desktop.
Save atl/232884 to your computer and use it in GitHub Desktop.
package main
// Revised after seeing pkg/http/url.go
import (
"fmt";
"strings";
)
func shouldEscape(c int) bool {
if c == 95 || c > 44 && c < 47 || c > 47 && c < 58 || c > 64 && c < 91 || c > 96 && c < 123 {
return false
}
return true;
}
func unicodeLen(c int) int {
switch {
case c < 128:
return 1
case c < 2048:
return 2
case c < 65536:
return 3
default: // c < 1114112,
return 4
}
return 4;
}
func URLEscape(s string) string {
spaceFlag := false;
hexCount, multibyteCount := 0, 0;
for _, c := range s {
switch shouldEscape(c) {
case c == ' ':
spaceFlag = true
default:
hexCount += unicodeLen(c); // extra hex pairs
multibyteCount += (unicodeLen(c) - 1); // extra percent signs
}
}
if !spaceFlag && hexCount == 0 {
return s
}
t := make([]byte, len(s)+2*hexCount+multibyteCount);
j := 0;
for _, c := range s {
switch {
case c == ' ':
t[j] = '+';
j++;
case shouldEscape(c) && c < 128:
t[j] = '%';
t[j+1] = "0123456789abcdef"[c>>4];
t[j+2] = "0123456789abcdef"[c&15];
j += 3;
case c < 128:
t[j] = uint8(c);
j++;
default:
r := strings.Bytes(string(c));
for _, b := range r {
t[j] = '%';
t[j+1] = "0123456789abcdef"[b>>4];
t[j+2] = "0123456789abcdef"[b&15];
j += 3;
}
}
}
return string(t);
}
func main() { fmt.Println(URLEscape("a b ç")) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment