Add Mumble support (#1245)
This commit is contained in:
130
vendor/github.com/vincent-petithory/dataurl/rfc2396.go
generated
vendored
Normal file
130
vendor/github.com/vincent-petithory/dataurl/rfc2396.go
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
package dataurl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Escape implements URL escaping, as defined in RFC 2397 (http://tools.ietf.org/html/rfc2397).
|
||||
// It differs a bit from net/url's QueryEscape and QueryUnescape, e.g how spaces are treated (+ instead of %20):
|
||||
//
|
||||
// Only ASCII chars are allowed. Reserved chars are escaped to their %xx form.
|
||||
// Unreserved chars are [a-z], [A-Z], [0-9], and -_.!~*\().
|
||||
func Escape(data []byte) string {
|
||||
var buf = new(bytes.Buffer)
|
||||
for _, b := range data {
|
||||
switch {
|
||||
case isUnreserved(b):
|
||||
buf.WriteByte(b)
|
||||
default:
|
||||
fmt.Fprintf(buf, "%%%02X", b)
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// EscapeString is like Escape, but taking
|
||||
// a string as argument.
|
||||
func EscapeString(s string) string {
|
||||
return Escape([]byte(s))
|
||||
}
|
||||
|
||||
// isUnreserved return true
|
||||
// if the byte c is an unreserved char,
|
||||
// as defined in RFC 2396.
|
||||
func isUnreserved(c byte) bool {
|
||||
return (c >= 'a' && c <= 'z') ||
|
||||
(c >= 'A' && c <= 'Z') ||
|
||||
(c >= '0' && c <= '9') ||
|
||||
c == '-' ||
|
||||
c == '_' ||
|
||||
c == '.' ||
|
||||
c == '!' ||
|
||||
c == '~' ||
|
||||
c == '*' ||
|
||||
c == '\'' ||
|
||||
c == '(' ||
|
||||
c == ')'
|
||||
}
|
||||
|
||||
func isHex(c byte) bool {
|
||||
switch {
|
||||
case c >= 'a' && c <= 'f':
|
||||
return true
|
||||
case c >= 'A' && c <= 'F':
|
||||
return true
|
||||
case c >= '0' && c <= '9':
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// borrowed from net/url/url.go
|
||||
func unhex(c byte) byte {
|
||||
switch {
|
||||
case '0' <= c && c <= '9':
|
||||
return c - '0'
|
||||
case 'a' <= c && c <= 'f':
|
||||
return c - 'a' + 10
|
||||
case 'A' <= c && c <= 'F':
|
||||
return c - 'A' + 10
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Unescape unescapes a character sequence
|
||||
// escaped with Escape(String?).
|
||||
func Unescape(s string) ([]byte, error) {
|
||||
var buf = new(bytes.Buffer)
|
||||
reader := strings.NewReader(s)
|
||||
|
||||
for {
|
||||
r, size, err := reader.ReadRune()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if size > 1 {
|
||||
return nil, fmt.Errorf("rfc2396: non-ASCII char detected")
|
||||
}
|
||||
|
||||
switch r {
|
||||
case '%':
|
||||
eb1, err := reader.ReadByte()
|
||||
if err == io.EOF {
|
||||
return nil, fmt.Errorf("rfc2396: unexpected end of unescape sequence")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !isHex(eb1) {
|
||||
return nil, fmt.Errorf("rfc2396: invalid char 0x%x in unescape sequence", r)
|
||||
}
|
||||
eb0, err := reader.ReadByte()
|
||||
if err == io.EOF {
|
||||
return nil, fmt.Errorf("rfc2396: unexpected end of unescape sequence")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !isHex(eb0) {
|
||||
return nil, fmt.Errorf("rfc2396: invalid char 0x%x in unescape sequence", r)
|
||||
}
|
||||
buf.WriteByte(unhex(eb0) + unhex(eb1)*16)
|
||||
default:
|
||||
buf.WriteByte(byte(r))
|
||||
}
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// UnescapeToString is like Unescape, but returning
|
||||
// a string.
|
||||
func UnescapeToString(s string) (string, error) {
|
||||
b, err := Unescape(s)
|
||||
return string(b), err
|
||||
}
|
||||
Reference in New Issue
Block a user