]> Cypherpunks repositories - gostls13.git/commitdiff
strconv: faster Unquote in common case
authorRuss Cox <rsc@golang.org>
Mon, 26 Sep 2011 17:59:12 +0000 (13:59 -0400)
committerRuss Cox <rsc@golang.org>
Mon, 26 Sep 2011 17:59:12 +0000 (13:59 -0400)
Also reject literal newline in " and ' quoted strings.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5139045

src/pkg/strconv/quote.go
src/pkg/strconv/quote_test.go

index 05e49d32ddfaae1fafea6cd0e4f23cda1af1a264..bbb9783ce8dc82988da354e16c62e927ce048a00 100644 (file)
@@ -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 {
index 4d615db443a25d37c5a334da6c8be50d2cf4ec34..0311f77a3a7fc15057fb26e1f3a48858b64257a0 100644 (file)
@@ -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."`)
+       }
+}