1
0
mirror of https://github.com/golang/go synced 2024-11-22 04:14:42 -07:00

strconv: remove dependency on bytes

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5759044
This commit is contained in:
Rob Pike 2012-03-06 15:25:42 +11:00
parent 4191ff2436
commit eab4261946
2 changed files with 34 additions and 31 deletions

View File

@ -52,7 +52,7 @@ var pkgDeps = map[string][]string{
"math/rand": {"L0", "math"}, "math/rand": {"L0", "math"},
"path": {"L0", "unicode/utf8", "strings"}, "path": {"L0", "unicode/utf8", "strings"},
"sort": {"math"}, "sort": {"math"},
"strconv": {"L0", "bytes", "unicode", "unicode/utf8", "math", "strings"}, "strconv": {"L0", "unicode", "unicode/utf8", "math", "strings"},
"strings": {"L0", "unicode", "unicode/utf8"}, "strings": {"L0", "unicode", "unicode/utf8"},
"unicode": {}, "unicode": {},
"unicode/utf16": {}, "unicode/utf16": {},

View File

@ -5,7 +5,6 @@
package strconv package strconv
import ( import (
"bytes"
"strings" "strings"
"unicode" "unicode"
"unicode/utf8" "unicode/utf8"
@ -14,8 +13,9 @@ import (
const lowerhex = "0123456789abcdef" const lowerhex = "0123456789abcdef"
func quoteWith(s string, quote byte, ASCIIonly bool) string { func quoteWith(s string, quote byte, ASCIIonly bool) string {
var buf bytes.Buffer var runeTmp [utf8.UTFMax]byte
buf.WriteByte(quote) buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations.
buf = append(buf, quote)
for width := 0; len(s) > 0; s = s[width:] { for width := 0; len(s) > 0; s = s[width:] {
r := rune(s[0]) r := rune(s[0])
width = 1 width = 1
@ -23,64 +23,65 @@ func quoteWith(s string, quote byte, ASCIIonly bool) string {
r, width = utf8.DecodeRuneInString(s) r, width = utf8.DecodeRuneInString(s)
} }
if width == 1 && r == utf8.RuneError { if width == 1 && r == utf8.RuneError {
buf.WriteString(`\x`) buf = append(buf, `\x`...)
buf.WriteByte(lowerhex[s[0]>>4]) buf = append(buf, lowerhex[s[0]>>4])
buf.WriteByte(lowerhex[s[0]&0xF]) buf = append(buf, lowerhex[s[0]&0xF])
continue continue
} }
if r == rune(quote) || r == '\\' { // always backslashed if r == rune(quote) || r == '\\' { // always backslashed
buf.WriteByte('\\') buf = append(buf, '\\')
buf.WriteByte(byte(r)) buf = append(buf, byte(r))
continue continue
} }
if ASCIIonly { if ASCIIonly {
if r <= unicode.MaxASCII && unicode.IsPrint(r) { if r <= unicode.MaxASCII && unicode.IsPrint(r) {
buf.WriteRune(r) buf = append(buf, byte(r))
continue continue
} }
} else if unicode.IsPrint(r) { } else if unicode.IsPrint(r) {
buf.WriteRune(r) n := utf8.EncodeRune(runeTmp[:], r)
buf = append(buf, runeTmp[:n]...)
continue continue
} }
switch r { switch r {
case '\a': case '\a':
buf.WriteString(`\a`) buf = append(buf, `\a`...)
case '\b': case '\b':
buf.WriteString(`\b`) buf = append(buf, `\b`...)
case '\f': case '\f':
buf.WriteString(`\f`) buf = append(buf, `\f`...)
case '\n': case '\n':
buf.WriteString(`\n`) buf = append(buf, `\n`...)
case '\r': case '\r':
buf.WriteString(`\r`) buf = append(buf, `\r`...)
case '\t': case '\t':
buf.WriteString(`\t`) buf = append(buf, `\t`...)
case '\v': case '\v':
buf.WriteString(`\v`) buf = append(buf, `\v`...)
default: default:
switch { switch {
case r < ' ': case r < ' ':
buf.WriteString(`\x`) buf = append(buf, `\x`...)
buf.WriteByte(lowerhex[s[0]>>4]) buf = append(buf, lowerhex[s[0]>>4])
buf.WriteByte(lowerhex[s[0]&0xF]) buf = append(buf, lowerhex[s[0]&0xF])
case r > unicode.MaxRune: case r > unicode.MaxRune:
r = 0xFFFD r = 0xFFFD
fallthrough fallthrough
case r < 0x10000: case r < 0x10000:
buf.WriteString(`\u`) buf = append(buf, `\u`...)
for s := 12; s >= 0; s -= 4 { for s := 12; s >= 0; s -= 4 {
buf.WriteByte(lowerhex[r>>uint(s)&0xF]) buf = append(buf, lowerhex[r>>uint(s)&0xF])
} }
default: default:
buf.WriteString(`\U`) buf = append(buf, `\U`...)
for s := 28; s >= 0; s -= 4 { for s := 28; s >= 0; s -= 4 {
buf.WriteByte(lowerhex[r>>uint(s)&0xF]) buf = append(buf, lowerhex[r>>uint(s)&0xF])
} }
} }
} }
} }
buf.WriteByte(quote) buf = append(buf, quote)
return buf.String() return string(buf)
} }
@ -329,7 +330,8 @@ func Unquote(s string) (t string, err error) {
} }
} }
var buf bytes.Buffer var runeTmp [utf8.UTFMax]byte
buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations.
for len(s) > 0 { for len(s) > 0 {
c, multibyte, ss, err := UnquoteChar(s, quote) c, multibyte, ss, err := UnquoteChar(s, quote)
if err != nil { if err != nil {
@ -337,14 +339,15 @@ func Unquote(s string) (t string, err error) {
} }
s = ss s = ss
if c < utf8.RuneSelf || !multibyte { if c < utf8.RuneSelf || !multibyte {
buf.WriteByte(byte(c)) buf = append(buf, byte(c))
} else { } else {
buf.WriteString(string(c)) n := utf8.EncodeRune(runeTmp[:], c)
buf = append(buf, runeTmp[:n]...)
} }
if quote == '\'' && len(s) != 0 { if quote == '\'' && len(s) != 0 {
// single-quoted must be single character // single-quoted must be single character
return "", ErrSyntax return "", ErrSyntax
} }
} }
return buf.String(), nil return string(buf), nil
} }