summaryrefslogtreecommitdiff
path: root/libgo/go/net/parse.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/net/parse.go')
-rw-r--r--libgo/go/net/parse.go207
1 files changed, 173 insertions, 34 deletions
diff --git a/libgo/go/net/parse.go b/libgo/go/net/parse.go
index e1d0130c9ac..c72e1c2eaf0 100644
--- a/libgo/go/net/parse.go
+++ b/libgo/go/net/parse.go
@@ -171,43 +171,30 @@ func xtoi2(s string, e byte) (byte, bool) {
return byte(n), ok && ei == 2
}
-// Integer to decimal.
-func itoa(i int) string {
- var buf [30]byte
- n := len(buf)
- neg := false
- if i < 0 {
- i = -i
- neg = true
- }
- ui := uint(i)
- for ui > 0 || n == len(buf) {
- n--
- buf[n] = byte('0' + ui%10)
- ui /= 10
- }
- if neg {
- n--
- buf[n] = '-'
- }
- return string(buf[n:])
-}
-
-// Convert i to decimal string.
-func itod(i uint) string {
- if i == 0 {
- return "0"
+// Convert integer to decimal string.
+func itoa(val int) string {
+ if val < 0 {
+ return "-" + uitoa(uint(-val))
}
+ return uitoa(uint(val))
+}
- // Assemble decimal in reverse order.
- var b [32]byte
- bp := len(b)
- for ; i > 0; i /= 10 {
- bp--
- b[bp] = byte(i%10) + '0'
+// Convert unsigned integer to decimal string.
+func uitoa(val uint) string {
+ if val == 0 { // avoid string allocation
+ return "0"
}
-
- return string(b[bp:])
+ var buf [20]byte // big enough for 64bit value base 10
+ i := len(buf) - 1
+ for val >= 10 {
+ q := val / 10
+ buf[i] = byte('0' + val - q*10)
+ i--
+ val = q
+ }
+ // val < 10
+ buf[i] = byte('0' + val)
+ return string(buf[i:])
}
// Convert i to a hexadecimal string. Leading zeros are not printed.
@@ -245,3 +232,155 @@ func last(s string, b byte) int {
}
return i
}
+
+// lowerASCIIBytes makes x ASCII lowercase in-place.
+func lowerASCIIBytes(x []byte) {
+ for i, b := range x {
+ if 'A' <= b && b <= 'Z' {
+ x[i] += 'a' - 'A'
+ }
+ }
+}
+
+// lowerASCII returns the ASCII lowercase version of b.
+func lowerASCII(b byte) byte {
+ if 'A' <= b && b <= 'Z' {
+ return b + ('a' - 'A')
+ }
+ return b
+}
+
+// trimSpace returns x without any leading or trailing ASCII whitespace.
+func trimSpace(x []byte) []byte {
+ for len(x) > 0 && isSpace(x[0]) {
+ x = x[1:]
+ }
+ for len(x) > 0 && isSpace(x[len(x)-1]) {
+ x = x[:len(x)-1]
+ }
+ return x
+}
+
+// isSpace reports whether b is an ASCII space character.
+func isSpace(b byte) bool {
+ return b == ' ' || b == '\t' || b == '\n' || b == '\r'
+}
+
+// removeComment returns line, removing any '#' byte and any following
+// bytes.
+func removeComment(line []byte) []byte {
+ if i := bytesIndexByte(line, '#'); i != -1 {
+ return line[:i]
+ }
+ return line
+}
+
+// foreachLine runs fn on each line of x.
+// Each line (except for possibly the last) ends in '\n'.
+// It returns the first non-nil error returned by fn.
+func foreachLine(x []byte, fn func(line []byte) error) error {
+ for len(x) > 0 {
+ nl := bytesIndexByte(x, '\n')
+ if nl == -1 {
+ return fn(x)
+ }
+ line := x[:nl+1]
+ x = x[nl+1:]
+ if err := fn(line); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// foreachField runs fn on each non-empty run of non-space bytes in x.
+// It returns the first non-nil error returned by fn.
+func foreachField(x []byte, fn func(field []byte) error) error {
+ x = trimSpace(x)
+ for len(x) > 0 {
+ sp := bytesIndexByte(x, ' ')
+ if sp == -1 {
+ return fn(x)
+ }
+ if field := trimSpace(x[:sp]); len(field) > 0 {
+ if err := fn(field); err != nil {
+ return err
+ }
+ }
+ x = trimSpace(x[sp+1:])
+ }
+ return nil
+}
+
+// bytesIndexByte is bytes.IndexByte. It returns the index of the
+// first instance of c in s, or -1 if c is not present in s.
+func bytesIndexByte(s []byte, c byte) int {
+ for i, b := range s {
+ if b == c {
+ return i
+ }
+ }
+ return -1
+}
+
+// stringsHasSuffix is strings.HasSuffix. It reports whether s ends in
+// suffix.
+func stringsHasSuffix(s, suffix string) bool {
+ return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
+}
+
+// stringsHasSuffixFold reports whether s ends in suffix,
+// ASCII-case-insensitively.
+func stringsHasSuffixFold(s, suffix string) bool {
+ if len(suffix) > len(s) {
+ return false
+ }
+ for i := 0; i < len(suffix); i++ {
+ if lowerASCII(suffix[i]) != lowerASCII(s[len(s)-len(suffix)+i]) {
+ return false
+ }
+ }
+ return true
+}
+
+// stringsHasPrefix is strings.HasPrefix. It reports whether s begins with prefix.
+func stringsHasPrefix(s, prefix string) bool {
+ return len(s) >= len(prefix) && s[:len(prefix)] == prefix
+}
+
+func readFull(r io.Reader) (all []byte, err error) {
+ buf := make([]byte, 1024)
+ for {
+ n, err := r.Read(buf)
+ all = append(all, buf[:n]...)
+ if err == io.EOF {
+ return all, nil
+ }
+ if err != nil {
+ return nil, err
+ }
+ }
+}
+
+// goDebugString returns the value of the named GODEBUG key.
+// GODEBUG is of the form "key=val,key2=val2"
+func goDebugString(key string) string {
+ s := os.Getenv("GODEBUG")
+ for i := 0; i < len(s)-len(key)-1; i++ {
+ if i > 0 && s[i-1] != ',' {
+ continue
+ }
+ afterKey := s[i+len(key):]
+ if afterKey[0] != '=' || s[i:i+len(key)] != key {
+ continue
+ }
+ val := afterKey[1:]
+ for i, b := range val {
+ if b == ',' {
+ return val[:i]
+ }
+ }
+ return val
+ }
+ return ""
+}