Commit ba444d84 authored by Russ Cox's avatar Russ Cox

strconv: faster Unquote in common case

Also reject literal newline in " and ' quoted strings.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5139045
parent 67d48daa
......@@ -288,6 +288,22 @@ func Unquote(s string) (t string, err os.Error) {
if quote != '"' && quote != '\'' {
return "", os.EINVAL
}
if strings.Index(s, "\n") >= 0 {
return "", os.EINVAL
}
// Is it trivial? Avoid allocation.
if strings.Index(s, `\`) < 0 && strings.IndexRune(s, int(quote)) < 0 {
switch quote {
case '"':
return s, nil
case '\'':
r, size := utf8.DecodeRuneInString(s)
if size == len(s) && (r != utf8.RuneError || size != 1) {
return s, nil
}
}
}
var buf bytes.Buffer
for len(s) > 0 {
......
......@@ -168,6 +168,7 @@ var unquotetests = []unQuoteTest{
{"`\\xFF`", `\xFF`},
{"`\\377`", `\377`},
{"`\\`", `\`},
{"`\n`", "\n"},
{"` `", ` `},
{"` `", ` `},
}
......@@ -189,6 +190,9 @@ var misquoted = []string{
"`\"",
`"\'"`,
`'\"'`,
"\"\n\"",
"\"\\n\n\"",
"'\n'",
}
func TestUnquote(t *testing.T) {
......@@ -211,3 +215,15 @@ func TestUnquote(t *testing.T) {
}
}
}
func BenchmarkUnquoteEasy(b *testing.B) {
for i := 0; i < b.N; i++ {
Unquote(`"Give me a rock, paper and scissors and I will move the world."`)
}
}
func BenchmarkUnquoteHard(b *testing.B) {
for i := 0; i < b.N; i++ {
Unquote(`"\x47ive me a \x72ock, \x70aper and \x73cissors and \x49 will move the world."`)
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment